Git 为单一项目设置 git 用户名和邮箱

自己有自己的开源项目,工作有工作的闭源项目,两者往往通过不同的 Git 帐号进行 commit 操作,那如何为不同的项目设置不同的 Git 帐号呢?

我们一般的操作都是:

git config --global user.name
git config --global user.email

这两步来设置 Git 帐号名与邮箱,但是针对特定项目,比如:

我 Git 的 global 用户名是 liumapp,但在 B 项目下想使用 lm 这个用户名来进行提交。

这种情况下,我们需要进行下列操作:

  • cd .git

  • vim config

添加下列代码:

[user]
    name=lm
    [email protected]
  • :wq 保存文件将立即生效,执行 commit 即可发现提交的用户为 lm。

一个git的使用错误unable to read askpass

今天在git push origin master时,竟然出现了错误 (gnome-ssh-askpass:32737): Gtk-WARNING **: cannot open display: error: unable to read askpass response from ‘/usr/libexec/openssh/gnome-ssh-askpass’根本原因是执行了该脚本

$ cat /etc/profile.d/gnome-ssh-askpass.sh
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass

解决方式

$ unset SSH_ASKPASS

再次执行git

$ git push origin master

不再提示错误。

Git撤销最后一次提交

Git可以使用reset重置来撤销提交。

方法一

撤销最后一次提交

git reset HEAD~1

执行后,状态重置为上一次提交,且撤回提交的文件的状态变回unstaged,即文件没有被git跟踪。

示例

$ git commit -m 'add test.html'
[master ade6d7e] add test.html
 1 file changed, 1 insertion(+)
 create mode 100644 test.html
$ git reset HEAD~1
$ git status
On branch master
Untracked files:
 (use "git add <file>..." to include in what will be committed)

    test.html

nothing added to commit but untracked files present (use "git add" to track)

撤回后test.html为Untracked files。

方法二

git reset --soft HEAD~1

使用–soft,执行后,状态重置为上一次提交,但撤回提交的文件add到git,被git跟踪。

示例

$ git commit -m 'add test.html'
[master 877b8f0] add test.html
 1 file changed, 1 insertion(+)
 create mode 100644 test.html

$ git reset --soft HEAD~1

clcaza@clcaza MINGW64 /d/webstormProjectsDemo/ngcli-demo (master)
$ git status
On branch master
Changes to be committed:
 (use "git reset HEAD <file>..." to unstage)

    new file: test.html

test.html状态为Changes to be committed

Git初始配置

一、配置提交时的用户名与邮件名称(注:只是标识本次commit是谁提交的)

1.1 通过命令的方式

$ git config --global user.name "songshuiyang"
$ git config --global user.email [email protected]

注: global 全局配置,在此电脑上的所有项目的git提交都会用这个用户名和邮件

1.2 通过修改配置文件的方式

文件路径: 用户目录/.gitconfig 文件

把name email改成(新增)自己的配置即可

[user]
        name = songshuiyang
        email = [email protected]

二、配置 短命令

2.1 通过命令的方式

$ git config --global alias.st status
$ git config --global alias.ci commit
$ git congig --global alias.co checkout
$ git congig --global alias.br branch

2.2 通过修改配置文件的方式

[alias]
    co = checkout
    ci = commit
    st = status
    cm = commit -m
    br = branch
    bm = branch -m
    bd = branch -D
    cb = checkout -b
    df = diff
    ls = log --stat
    lp = log -p
    plo = pull origin
    plode = pull origin develop
    pho = push origin

三、配置文件

Git的三个配置文件

  • 版本库级别的配置文件,文件路径: 项目路径/.git/config

  • 全局配置文件, 文件路径: 用户目录/.gitconfig

  • 系统级配置文件,文件路径: 安装目录/etc目录下

优先级: 版本库级别的配置文件 > 全局配置文件 > 系统级配置文件

四、文件 .git/index

实际上就是一个包括文件索引的目录树,像是一个虚拟的工作区,记录了文件名和文件的状态信息(时间戳和文件长度),文件的内容保存在.git/objects目录下,文件索引建立了文件和对象库中对象实体之间的对应

工作区,版本区,暂存区原理图

未分类

git 分支管理 推送本地分支到远程分支等

1、创建本地分支 local_branch

git branch local_branch

2、创建本地分支local_branch 并切换到local_branch分支

git checkout -b local_branch

3、切换到分支local_branch

git checkout local_branch

4、推送本地分支local_branch到远程分支 remote_branch并建立关联关系

a.远程已有remote_branch分支并且已经关联本地分支local_branch且本地已经切换到local_branch

git push

b.远程已有remote_branch分支但未关联本地分支local_branch且本地已经切换到local_branch

git push -u origin/remote_branch

c.远程没有有remote_branch分支并,本地已经切换到local_branch

git push origin local_branch:remote_branch

5、删除本地分支local_branch

git branch -d local_branch

6、删除远程分支remote_branch

git push origin  :remote_branch

git branch -m | -M oldbranch newbranch 重命名分支,如果newbranch名字分支已经存在,则需要使用-M强制重命名,否则,使用-m进行重命名。

git branch -d | -D branchname 删除branchname分支

git branch -d -r branchname 删除远程branchname分支

7、查看本地分支

git branch

8、查看远程和本地分支

git branch -a

除了 pull 和 push 你应该知道 git 的操作

git 仓库简单示意图

| 工作区(Working) | 暂存区(Staging) | 版本库(Local repo)| 远程仓库(Remote repo)|

    |---- git add ---->|--- git commit --->|---- git push --->|
    |----------- git commit -am  --------->|---- git push --->|
    |<- git checkout --|<--- git reset ----|<--- git pull ----|
    |<--------- git reset --hard HEAD -----|<--- git pull ----|

与远程分支建立追踪关系(tracking)

git branch --set-upstream master origin/master

设置 rebase 让历史变得清晰

git config --global branch.autosetuprebase always # 所有分支
git config branch.master.rebase true # 指定分支

查看 git 配置信息

git config --list

禁止终端显示中文文件名为 xxxxxx 形式

git config --global core.quotepath false

更美观的输出 log

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative -10
git log

查看简要的 log

git log --oneline --5

强制更新,覆盖本地修改

git fetch --all
git reset --hard origin/master

操作撤销(还没有 push)

git reset --soft 3ce07 # 回滚到多个提交之前,但保留没有提交的改变(不回滚工作区和缓存区)
git reset --hard HEAD # 回滚到最近一次的提交(会回滚工作区和缓存区)

操作撤销 (已经 push)

git revert c011e # 用一个新提交来消除一个历史提交所做的修改

版本撤销

git log
git reset --hard e54dd31

修改 commit 注释

git commit --amend -m "Fixes bug #42"

版本恢复

git reflog
git reset --hard c80ae4f

隐藏工作区

git stash # 暂存改动(默认备注)
git stash save "暂存头部样式修改" # 暂存改动,自定义备注
git stash list # 查看暂存的改动列表
git stash pop --index stash@{0} # 释放指定暂存项
git stash pop # 释放全部暂存的改动
git stash drop # 删除暂存的改动

查看修改日志

git log --author=yida # 查看特定成员的更新记录
git log --grep="等待页面" # 按关键字搜索更新记录
git log ./package.json # 查看指定文件的更改日志

打 Tag 操作

git tag v0.9 # 在 HEAD 打"轻 tag"
git tag -am "xxx" v0.9 # 在 HEAD 打"注解 tag"
git tag v0.9 a032c # 在指定提交打"轻 tag"
git tag -a v0.1 -m "xxx" a032c # 在指定提交打"注解 tag"
git tag # 查看打过的 tag
git tag -n # 查看打过的 tag 及注解
git push origin v1.0 # 将 tag 推送到远程
git push origin --tags # 推送全部尚未推送到远程的 tag
git tag -d v0.9 # 删除本地 tag
git push origin :refs/tags/v0.9 # 从远程删除 tag

基于某个 tag 创建新分支

假设在你的主分支上有一个 tag 为 v1.0 , 主分支的名字为 master:

git branch new_branch v1.0 # 以 tag v1.0 创建新的分支 newbranch
git checkout new_branch # 切换到分支 newbranch
git push origin new_branch # 把本地 newbranch 分支提交到远程仓库

添加忽略文件

echo '*~' >> .gitignore
git add .gitignore

添加全局忽略文件

git config --global core.excludesfile ~/.gitignore_global
vim ~/.gitignore_global

加入要忽略的文件名

Git 使用问题

问题1:怎样设置 git 操作免输账号密码?

1、在主文件夹下创建文件 .git-credentials, 用vim编辑:

cd ~
touch .git-credentials
vim .git-credentials

2、在 .git-credentials 添加 https://{username}:{password}@github.com,例如:

https://yida:[email protected]

3、在终端下执行命令:

git config --global credential.helper store

4、查看到 ~/.gitconfig 文件新加入一项配置:

[credential]
helper = store

以后 git 操作就不再需要密码验证

问题2:怎样设置 git 忽略已经被提交的文件?

git update-index --assume-unchanged .ftpconfig # 忽略跟踪 .ftpconfig
git update-index --no-assume-unchanged .ftpconfig # 恢复跟踪 .ftpconfig
git ls-files -v | grep -e "^[hsmrck]" # 查看当前被忽略、已经纳入版本库管理的文件

问题3: 如何把在本地 A 分支上的一个 commit(7b31b7)放到本地 B 分支上?

git checkout B
git cherry-pick 7b31b7

问题4. 查看谁弄乱了文件 index.php 的代码?

git blame index.php

问题5. 怎样恢复丢失的提交?

git reflog # 查看该所有操作日志 -- 例如,丢失的提交信息如下:
# 794b305 HEAD@{24}: rebase: 修改开户状态相关
git branch recover-branch 794b305 # 在丢失的 commit(794b305) 上创建一个新分支, 即可恢复此次提交

Git 工作流的正确打开方式

未分类

前言

一直在使用git做版本控制,也一直工作很顺利,直到和别人发生冲突的时候。这才注意到git 工作流并不是那么简单。比如,之前遇到的清理历史。百度到的资料很多,重复性也很多,但实践性操作很少,我很难直接理解其所表达的含义。直接望文生义经常得到错误的结论,只能用时间去检验真理了,不然看到的结果都是似懂非懂,最后还是一团糟。

学习git工作流

一、最简单的使用,不推荐

1.1 创建仓库

$ pwd
/home/ryan/workspace/l4git-workflow
$ touch readme.md
$ ls
readme.md
$ touch .gitignore
$ git init
初始化空的 Git 仓库于 /home/ryan/workspace/l4git-workflow/.git/
$ touch test.txt
$ git add .
$ git commit -m "init"
[master (根提交) dae77d6] init
 3 files changed, 12 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 readme.md
 create mode 100644 test.txt
$ git remote add origin [email protected]:Ryan-Miao/l4git-workflow.git
$ git push -u origin master
对象计数中: 5, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (5/5), 388 bytes | 0 bytes/s, 完成.
Total 5 (delta 0), reused 0 (delta 0)
To [email protected]:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。

未分类

1.2 模拟用户A

git clone [email protected]:Ryan-Miao/l4git-workflow.git
git checkout a
touch a.txt
//write one
//....
$ git add .
$ git commit -m "one"
[a 53ff45e] one
 2 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 a.txt

此时,a还没有提交到 origin 。 git log 如下:

未分类

1.3 模拟用户B

git clone [email protected]:Ryan-Miao/l4git-workflow.git
git checkout b
$ touch b.txt

//write something
//…

$ git add .
$ git commit -m "b write one"
[b 847078e] b write one
 1 file changed, 1 insertion(+)
 create mode 100644 b.txt

//write something
//….

$ git add . $ git commit -m "b write two" [b 3f30f41] b write two 1 file changed, 2 insertions(+), 1 deletion(-)

此时,git log如下

未分类

1.4 模拟用户A

A和B分别是在本地开发,所以这种顺序是未知的,也许A比B先commit一次,也许B先commit一次。这里的先后是指commit的时间戳。但都是在本地提交的代码。
write something

git add .
git commit -m "a write two"

wirte something

git add .
git commit -m "write three"

A push to server branch a

$ git push origin a:a
Total 0 (delta 0), reused 0 (delta 0)
To [email protected]:Ryan-Miao/l4git-workflow.git
 * [new branch]      a -> a

A created a Pull Request

未分类

未分类

1.5 模拟用户C

C review the PR and then merged it.

未分类

此时,github的历史如下:

未分类

可以看出,merge的时候多了一次commit,message默认为

Merge pull request #1 from Ryan-Miao/a...

现在看起来,只有a一个人的历史记录,还算清楚,a做了3次提交。

1.6 模拟用户B

用户B提交前先pull master,更新最新的代码到本地,防止冲突。

git fetch
git merge origin/master

此时log看起来有点乱。如下:

未分类

让人感到混乱的是b原来的历史只有自己的提交,更新了master到本地之后,历史记录被插入了master中的历史。于是,发现原来自己干净的历史被中间插入多次commit。甚至两次merge master的日志显得又长又碍眼。但不管怎么说,B还是要提交的。

于是,B提交到远程分支b:

未分类

1.7 模拟用户C

这时候,A完成了feature a,然后提了PR,然后找他人C merge了。而后,B也完成了feature b,提了PR,需要review and merge。 C review之后,approved, 然后D review, D merge。

此时,项目基本走上正规。feature一个一个添加进去,重复之前的工作流程: fetch -》 work -》 commit -》 push -》 PR -》 merged。
然后,项目历史就变成了这样:

未分类

一眼大概看起来还好,每次都能看到提交历史,只要不是message写的特别少,差不多可以理解最近提交的内容。然而,仔细一看,顺序好像不对。目前一共两个feature,但历史却远远超过2个。没关系,保证细粒度更容易体现开发进度。然而,这些历史并不是按照feature的发布顺序,那么,当我想要找到feature a的时候就很难串联起来。如果commit足够多,时间跨度足够大,甚至根本看不出来feature a到底做了哪些修改。

这时候想要使用图形化git 历史工具来帮助理解历史:

未分类

这里,还好,还勉强能看出走向。但当10个上百个人同时开发的话,线简直不能看了,时间跨度足够大的话,线也看不完。

因此,这种模式,正是我们自己当前采用的模式。差评。这还不算完,后面更大的困难来了。最先发布的feature a出了问题,必须回滚。怎么做到。关于回滚,就是另一个话题了。 但我们应该知道使用revert而不是reset. 但revert只能回滚指定的commit,或者连续的commit,而且revert不能revert merge操作。这样,想回滚feature a, 我们就要找到a的几次提交的版本号,然后由于不是连续的,分别revert。这会造成复杂到不想处理了。好在github给了方便的东西,PR提供了revert的机会。找到以前的PR。

未分类

但是,这绝对不是个好操作!

二、推荐的工作流程

造成上述现象的原因是因为各自异步编程决定的。因为每个人都可以随时间提交,最后合并起来的时候以提交时间戳来作为序列的依据,就会变成这样。因此,当需要提交的远程服务器的时候,如果能重写下commit的时间为当前时间,然后push到服务端,历史就会序列到最后了。

2.1 模拟用户C

C用户新下载代码。

$ git clone [email protected]:Ryan-Miao/l4git-workflow.git c正克隆到 'c'...
remote: Counting objects: 28, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 28 (delta 8), reused 22 (delta 4), pack-reused 0
接收对象中: 100% (28/28), 5.90 KiB | 0 bytes/s, 完成.
处理 delta 中: 100% (8/8), 完成.
检查连接... 完成。

然后编辑,提交

$ cd c
$ git config user.name "C"
$ ls
a.txt  b.txt  readme.md  test.txt
$ vim c.txt
$ git add .
$ git commit -m "C write one"
[master cf3f757] C write one
 1 file changed, 2 insertions(+)
 create mode 100644 c.txt

2.2 模拟用户D

同时,D也需要开发新feature

$ git clone [email protected]:Ryan-Miao/l4git-workflow.git d正克隆到 'd'...
remote: Counting objects: 28, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 28 (delta 8), reused 22 (delta 4), pack-reused 0
接收对象中: 100% (28/28), 5.90 KiB | 0 bytes/s, 完成.
处理 delta 中: 100% (8/8), 完成.
检查连接... 完成。
$ cd d
/d$ git config user.name "D"
/d$ vim d.txt
/d$ git add .
/d$ git commit -m "d write one"
[master db7a6e9] d write one
 1 file changed, 1 insertion(+)
 create mode 100644 d.txt

2.3 C继续开发

$ vim c.txt
$ git add .
$ git commit -m "c write two"
[master 01b1210] c write two
 1 file changed, 1 insertion(+)

2.4 D继续开发

/d$ vim d.txt
/d$ git add .
/d$ git commit -m "d write two"
[master a1371e4] d write two
 1 file changed, 1 insertion(+)

2.5 C 提交

$ vim c.txt 
$ git add .
$ git commit -m "c write three"
[master 13b7dde] c write three
 1 file changed, 1 insertion(+)

C开发结束,提交到远程

$ git status
位于分支 master
您的分支领先 'origin/master' 共 3 个提交。
  (使用 "git push" 来发布您的本地提交)
无文件要提交,干净的工作区
$ git push origin master:C
对象计数中: 9, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (6/6), 完成.
写入对象中: 100% (9/9), 750 bytes | 0 bytes/s, 完成.
Total 9 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 1 local object.
To [email protected]:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> C

2.6 C 提PR

然后,create a Pull Request.

未分类

2.7 C修改再push

然后,发现还有个bug要修复,再次修改提交到远程C

$ vim c.txt 
$ git add .
$ git commit -m "C finish something else"
[master 2c5ff94] C finish something else
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git push origin master:C
对象计数中: 3, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (3/3), 301 bytes | 0 bytes/s, 完成.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To [email protected]:Ryan-Miao/l4git-workflow.git
   13b7dde..2c5ff94  master -> C

2.8 C发现提交次数过多,历史太乱,合并部分历史

这时,发现一个问题,由于C在开发过程中提交了多次,而这几次提交的message其实没有多大意思,只是因为C可能为了保存代码,也可能是暂存。总之,C的前3次提交的message的含义其实是一样的,都是创建C文件,都是一个主题,那么为了维护历史的干净。最好把这3条信息合并成一条C create file c.txt。

参考git 合并历史,我们需要将3次历史合并成显示为一次。

查看git历史,找到需要合并的起始区间

$ git log --oneline
2c5ff94 C finish something else
13b7dde c write three
01b1210 c write two
cf3f757 C write one
7151f4c 记录操作。
0bfe562 Merge pull request #2 from Ryan-Miao/b_remote
d81ce20 Merge remote-tracking branch 'origin/master' into b
2d74cfb Merge pull request #1 from Ryan-Miao/a
b90a3dd write three
4b1629e a write two
3f30f41 b write two
847078e b write one
53ff45e one
dae77d6 init

显然,是要合并cf3f757到13b7dde。那么找到前一个的版本号为7151f4c

git rebase - i 7151f4c

然后进入交互界面,因为我们想要把第3次和第2次以及第1次提交信息合并。将第3次的类型修改为squash, 意思是和第2次合并。然后将第2次的类型修改为squash, 同样是指合并的前一个commit。

未分类

不同git的交互略有不同,之前在windows上的git bash是完全按照vim的命令修改的。本次测试基于Ubuntu,发现存档命令为ctel + X。确认后进入下一个界面,合并3次提交后需要一个message

未分类

删除或者anyway you like, 更改message。存档。完成。

$ git rebase -i 7151f4c
[分离头指针 e3764c5] c create  file c.txt
 Date: Fri Oct 20 22:06:24 2017 +0800
 1 file changed, 4 insertions(+)
 create mode 100644 c.txt
Successfully rebased and updated refs/heads/master.

Tips

当在rebase过程中出现了失误,可以使用git rebase –abort返回初始状态。如果发现冲突,则可以解决冲突,然后git rebase –continue .

好像已有 rebase-merge 目录,我怀疑您正处于另外一个变基操作
过程中。 如果是这样,请执行

git rebase (--continue | --abort | --skip)

如果不是这样,请执行

rm -fr "/home/ryan/temp/c/.git/rebase-merge"

然后再重新执行变基操作。 为避免丢失重要数据,我已经停止当前操作。

此时,查看log, 显然,C的那三次提交已经合并了。

$ git log --oneline
50b9fe9 C finish something else
e3764c5 c create  file c.txt
7151f4c 记录操作。
0bfe562 Merge pull request #2 from Ryan-Miao/b_remote
d81ce20 Merge remote-tracking branch 'origin/master' into b
2d74cfb Merge pull request #1 from Ryan-Miao/a
b90a3dd write three
4b1629e a write two
3f30f41 b write two
847078e b write one
53ff45e one
dae77d6 init

2.9 C再次push

之前的push已经不能用了。需要开新分支推送过去。因为 rebase 只能在本地分支做。不要修改公共分支 。

$ git push origin master:C
To [email protected]:Ryan-Miao/l4git-workflow.git
 ! [rejected]        master -> C (non-fast-forward)
error: 无法推送一些引用到 '[email protected]:Ryan-Miao/l4git-workflow.git'
提示:更新被拒绝,因为推送的一个分支的最新提交落后于其对应的远程分支。
提示:检出该分支并整合远程变更(如 'git pull ...'),然后再推送。详见
提示:'git push --help' 中的 'Note about fast-forwards' 小节。

选择推送的新分支C2

$ git push origin master:C2
对象计数中: 6, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (5/5), 完成.
写入对象中: 100% (6/6), 569 bytes | 0 bytes/s, 完成.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To [email protected]:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> C2

创建新的PR

未分类

2.10 新的merge方式: rebase

通过开始的普通流程发现,每次merge的时候,都会多出一条新的提交信息,这让历史看起来很奇怪。那么,可以选择rebase到master,变基,就是重新以master为基本,把当前的提交直接移动到master的后面。不会因为提交时间的离散导致多次commit的message被拆散。 选择 rebase and merge

未分类

未分类

这时候,可以看到C提交的两次信息都是最新的,没有发生交叉。而且也没有产生多余的merge信息。

未分类

有人会问,那么岂不是看不到PR的地址了。点开C的历史。可以看到message下方是有PR的编号的:

未分类

对了,刚开始的PR要记得close

未分类

2.11 这时候D也完成了

/d$ git push origin master:D
对象计数中: 10, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (7/7), 完成.
写入对象中: 100% (10/10), 4.49 KiB | 0 bytes/s, 完成.
Total 10 (delta 2), reused 4 (delta 1)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To [email protected]:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> D

提PR, 这时候,如果采用merge:

未分类

未分类

结果必然发现,1) d提交message被按照时间分散插入历史了(被插入到c的历史之前), 2)多了一次 Merge pull request #5 from Ryan-Miao/D..的提交信息。同开头所述一样,历史开始变得混乱了。那么,这种问题怎么办呢?

2.12 提交前rebase

就像C rebase后merge到master一样。我们一样可以在本地做到这样的事情。在本地rebase,让我们本次feature的提交全部插到master节点之后,有序,而且容易revert。
本次,以新的E和F交叉commit为例子,最终将得到各自分开的历史

E:

$ git clone [email protected]:Ryan-Miao/l4git-workflow.git e
正克隆到 'e'...
remote: Counting objects: 52, done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 52 (delta 18), reused 36 (delta 7), pack-reused 0
接收对象中: 100% (52/52), 7.91 KiB | 0 bytes/s, 完成.
处理 delta 中: 100% (18/18), 完成.
检查连接... 完成。

$ cd e
/e$ vim e.txt
/e$ git add .
/e$ git config user.name "E"
/e$ git commit -m "e commit one"
[master 77ecd73] e commit one
 1 file changed, 1 insertion(+)
 create mode 100644 e.txt

F:

$ git clone [email protected]:Ryan-Miao/l4git-workflow.git f
正克隆到 'f'...
remote: Counting objects: 52, done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 52 (delta 18), reused 36 (delta 7), pack-reused 0
接收对象中: 100% (52/52), 7.91 KiB | 0 bytes/s, 完成.
处理 delta 中: 100% (18/18), 完成.
检查连接... 完成。

$ cd f
$ vim f.txt
$ git config user.name "F"
$ git add .
$ git commit -m "d write one"
[master b41f8c5] d write one
 1 file changed, 2 insertions(+)
 create mode 100644 f.txt

E:

/e$ vim e.txt
/e$ git add .
/e$ git commit -m "e write two"
[master 2b8c9fb] e write two
 1 file changed, 1 insertion(+)

F:

$ vim f.txt
$ git add .
$ git commit -m "f write two"
[master de9051b] f write two
 1 file changed, 1 insertion(+)

E:

/e$ vim e.txt 
/e$ git add .
/e$ git commit -m "e write three"
[master b1b9f6e] e write three
 1 file changed, 2 insertions(+)

这时候,e完成了,需要提交。提交前先rebase:

/e$ git fetch
/e$ git rebase origin/master
当前分支 master 是最新的。

然后,再提交

/e$ git push origin master:E
对象计数中: 9, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (6/6), 完成.
写入对象中: 100% (9/9), 753 bytes | 0 bytes/s, 完成.
Total 9 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 1 local object.
To [email protected]:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> E

然后, PR, merge.

同样F:

$ git status
位于分支 master
您的分支领先 'origin/master' 共 2 个提交。
  (使用 "git push" 来发布您的本地提交)
无文件要提交,干净的工作区
$ git fetch 
remote: Counting objects: 12, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 12 (delta 6), reused 6 (delta 3), pack-reused 0
展开对象中: 100% (12/12), 完成.
来自 github.com:Ryan-Miao/l4git-workflow
   24c6818..f36907c  master     -> origin/master
 * [新分支]          E          -> origin/E
$ git rebase origin/master
首先,回退分支以便在上面重放您的工作...
应用:d write one
应用:f write two

$ git push origin master:F
对象计数中: 6, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (4/4), 完成.
写入对象中: 100% (6/6), 515 bytes | 0 bytes/s, 完成.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To [email protected]:Ryan-Miao/l4git-workflow.git
 * [new branch]      master -> F

PR, rebase and merge。 这时候看history:

未分类

按照前几次的做法,E和F交叉在本地提交,每次commit的时间戳也是交叉,最终合并到master的时候,历史并没有被拆散。而是像我们期待的一样,顺序下来。这才是我们想要的。通过看图形化界面也能看出区别:

绿色的线是master

未分类

那么,操作便是fetch-》rebase。事实上,可以二合一为:

git pull --rebase origin master

未分类

三、最终结果

在都没提交到server的时候, 历史是分散在各个开发者的本地,但commit时间有先后。

未分类

按照rebase的用法,提交前rebase一次,就可以使得一个feature的提交串联到一起

未分类

最终在github的commit看起来也就是顺畅的多

未分类

四、金科玉律

想维持树的整洁,方法就是:在git push之前,先git fetch,再git rebase。

git fetch origin master
git rebase origin/master
git push

或者

git pull --rebase origin master

只要你把变基命令当作是在推送前清理提交使之整洁的工具,并且只在从未推送至共用仓库的提交上执行变基命令,就不会有事。 假如在那些已经被推送至共用仓库的提交上执行变基命令,并因此丢弃了一些别人的开发所基于的提交,那你就有大麻烦了,你的同事也会因此鄙视你。

如果你或你的同事在某些情形下决意要这么做,请一定要通知每个人执行 git pull –rebase 命令,这样尽管不能避免伤痛,但能有所缓解。

  • 绝对不要在公共(远程分支)上rebase,也就是说,如果没有必要就不要在github merge的时候选择rebase,而是用上述的办法,在本地自己的分支推送前rebase
  • 绝对不可以在公共分支上reset,也不要用–force
  • 单独功能的多次提交要学会合并提交,保持提交的简洁。
  • 提交message尽量能概括修改内容。

【Git】Ubuntu升级Git版本

问题描述

在使用Ubuntu自带的Git进行提交的时候出现错误

Please upgrade your git client.

用apt-get命令升级git时,提示Git已经是最新版本

$ sudo apt-get install git

Reading package lists... Done
Building dependency tree
Reading state information... Done
git is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded. 

但是我在官网上看的Git版本大于我的Git版本,所以需要更新Git的版本库

解决方法

要获得最新版本的Git,需要在Ubuntu中添加Git的维护者团队PPA(归档包)到软件源列表,然后更新源列表并升级Git

sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install -y git

然后查看Git版本

git --version

实用的升级安装方法php,Nginx,mysql,zabbix等

升级版本编译安装当然Ok,依赖问题处理起来非常之繁琐,现在直接通过apt源来升级版本非常简便,下面我们来拿php做个升级实验

1. 添加下面两行到/etc/apt/sources.list,并将jessie替换为自己所使用的版本名称:

deb http://mirrors.ustc.edu.cn/dotdeb jessie all
deb-src http://mirrors.ustc.edu.cn/dotdeb jessie all

2. 可选项:

如果你想在Debian Squeeze上安装PHP5.4的话,再添加下面这两行:

deb http://mirrors.ustc.edu.cn/dotdeb squeeze-php54 all
deb-src http://mirrors.ustc.edu.cn/dotdeb squeeze-php54 all

如果你想在Debian Wheezy上安装未启用Zend Thread Safety的PHP5.6的话,再添加下面这两行:

deb http://mirrors.ustc.edu.cn/dotdeb wheezy-php56 all
deb-src http://mirrors.ustc.edu.cn/dotdeb wheezy-php56 all

如果你想在Debian Wheezy上安装启用Zend Thread Safety的PHP5.6的话,再添加下面这两行:

deb http://mirrors.ustc.edu.cn/dotdeb wheezy-php56-zts all
deb-src http://mirrors.ustc.edu.cn/dotdeb wheezy-php56-zts all

如果你想在Debian Wheezy上安装PHP5.5的话,再添加下面这两行:

deb http://mirrors.ustc.edu.cn/dotdeb wheezy-php55 all
deb-src http://mirrors.ustc.edu.cn/dotdeb wheezy-php55 all

3. 然后导入合适的GnuPG key

wget https://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | sudo apt-key add -

4. 运行

apt-get update

升级php例子:

升级前

一系列操作

401 2017-10-21 09:25:26 echo “deb http://packages.dotdeb.org wheezy-php56 all” >> /etc/apt/sources.list.d/dotdeb.list
402 2017-10-21 09:25:32 echo “deb-src http://packages.dotdeb.org wheezy-php56 all” >> /etc/apt/sources.list.d/dotdeb.list
403 2017-10-21 09:25:39 wget http://www.dotdeb.org/dotdeb.gpg -O- | apt-key add –
405 2017-10-21 09:26:17 dpkg -l |grep php
413 2017-10-21 09:28:30 for pkg in `dpkg -l |grep php |awk ‘{print $2}’`;do dpkg -P $pkg; done
425 2017-10-21 09:29:28 aptitude update
426 2017-10-21 09:29:46 aptitude install php5-fpm php5-cgi php5-cli php5-curl php5-gd php5-mcrypt php5-mysql php5-memcache php5-xmlrpc php5-dev libapache2-mod-php5

然后看看升级后的版本

未分类

ok升级完成,类似nginx等都可以参考这个方法。

zabbix 创建自定义监控项

1、打开zabbix_agentd.conf中自定义监控项

[root@abcopenstack script]# tailf -10 /usr/local/etc/zabbix_agentd.conf
UnsafeUserParameters=1
Include=/usr/local/etc/zabbix_agentd.userparams.conf #链接自定义监控项的路径

2、创建自定义监控项文件(监控项的名称要有zabbix web界面一致)

未分类

[root@abcopenstack script]# vim /usr/local/etc/zabbix_agentd.userparams.conf
UserParameter=check_link,/bin/bash /usr/local/etc/script/check_link.sh

3、所定义的脚本需要定义为可执行权限

[root@abcopenstack script]# chmod 755 check_link.sh
[root@abcopenstack script]# ll
total 4
-rwxr-xr-x 1 root root 95 Oct 13 14:33 check_link.sh

4、重启zabbix_agentd

5、使用zabbix_get测试自定义的监控项是否能获取数据

[root@abcopenstack script]# zabbix_get -s 127.0.0.1 -p 10050 -k check_link

6、zabbix web 界面添加监控项

6.1 点击监控项

未分类

6.2 创建监控项

未分类

7、定义监控项图像

未分类

8、查看图像

未分类