博学笃行·盛德日新

git自学3:git分支管理


git

git分支管理

1. 创建新的dev分支

# shell $> git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b参数表示创建并切换, 相当于一下两条命令

# shell $> git branch dev
# shell $> git checkout dev
Switched to branch 'dev'

将本地刚创建的的dev分支和远程进行关联并推送

# shell $> git push --set-upstream origin dev

2. 查看远程仓库

# shell $> git branch -r
  origin/dev
  origin/master

3. 从远程拉取test分支并切换到test分支

方式1:

# shell $> git checkout -b test origin/test

使用该方式会在本地新建分支x,并自动切换到该本地分支x。
采用此种方法建立的本地分支会和远程分支建立映射关系。

方式2:

git fetch origin 远程分支名x:本地分支名x

使用该方式会在本地新建分支x,但是不会自动切换到该本地分支x,需要手动checkout。
采用此种方法建立的本地分支不会和远程分支建立映射关系。

4. 合并dev分支的内容到test分支

首先, 切换到dev分支, 对内容进行变更和提交

# shell $> git checkout dev
Switched to branch 'dev'
Your branch is up to date with 'origin/dev'.

# shell $> echo 'new file to dev' > dev-file.txt

# shell $> git add dev-file.txt

# shell $> git commit -m "add a file"
[dev 41dd7c6] add a file
 1 file changed, 1 insertion(+)
 create mode 100644 dev-file.txt

然后, 切换到test分支, 进行合并操作

# shell $> git checkout test
Switched to branch 'test'
Your branch is up to date with 'origin/test'.

# shell $> git merge dev
Updating dd13a7a..41dd7c6
Fast-forward
 dev-file.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 dev-file.txt

这里表示将dev分支的更改合并到当前分支

5. 删除dev分支

# shell $> git branch -d dev
warning: not deleting branch 'dev' that is not yet merged to
         'refs/remotes/origin/dev', even though it is merged to HEAD.
error: The branch 'dev' is not fully merged.
If you are sure you want to delete it, run 'git branch -D dev'.

当还有未提交到远程的修改时,是不能直接删除的,如果一定想要删除, 需要使用 git branch -D dev 进行删除
切换回dev分支,进行提交并push到远程

# shell $> git checkout dev
Switched to branch 'dev'
Your branch is ahead of 'origin/dev' by 1 commit.
  (use "git push" to publish your local commits)

# shell $> git push
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: To create a merge request for dev, visit:
remote:   http://git.example.com/foreverich/mygitdir/merge_requests/new?merge_request%5Bsource_branch%5D=dev
remote:
To git.example.com:foreverich/mygitdir.git
   dd13a7a..41dd7c6  dev -> dev

再次进行分支删除操作

# shell $> git branch -d dev
error: Cannot delete branch 'dev' checked out at '/Users/foreverich/git/git.example.com/foreverich/mygitdir'

这个提示是说, 你不能在当前分支dev删除当前分支dev, 所以我们切换到其他分支后, 再删除

# shell $> git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

# shell $> git branch -d dev
warning: deleting branch 'dev' that has been merged to
         'refs/remotes/origin/dev', but not yet merged to HEAD.
Deleted branch dev (was 41dd7c6).

现在还是有warning, 告诉我们虽然删除了本地dev分支,但是远程的dev分支并没有删除
删除远程dev分支

# shell $> git push origin --delete dev
To git.example.com:foreverich/mygitdir.git
 - [deleted]         dev

6. 冲突解决

# shell $> vim readme.md

# shell $> git add readme.md

# shell $> git commit -m "change test to tabt"
[master 1f94577] change test to tabt
 1 file changed, 1 insertion(+), 1 deletion(-)

# shell $> git checkout test
Switched to branch 'test'
Your branch is up to date with 'origin/test'.

# shell $> vim readme.md

# shell $> git add readme.md

# shell $> git commit -m "change test to tcft"
[test 13cb129] change test to tcft
 1 file changed, 1 insertion(+), 1 deletion(-)

# shell $> git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

# shell $> git merge test
Auto-merging readme.md
CONFLICT (content): Merge conflict in readme.md
Automatic merge failed; fix conflicts and then commit the result.

# shell $> cat readme.md
<<<<<<< HEAD
git tabt
=======
git tcft
>>>>>>> test
git new line

Git用<<<<<<<=======>>>>>>>标记出不同分支的内容
我们对冲突的地方进行修改, 修改后的内容

# shell $> cat readme.md
git tabcft
git new line

# shell $> git add readme.md 
# shell $> git commit -m "fixed conflict"
[master cf810e4] fixed conflict

我们再回到test分支, 合并master的变更操作

# shell $> git checkout test
Switched to branch 'test'
Your branch is ahead of 'origin/test' by 1 commit.
  (use "git push" to publish your local commits)

# shell $> cat readme.md
git tcft
git new line

# shell $> git merge master
Updating 13cb129..6dc69de
Fast-forward
 readme.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

# shell $> cat readme.md
git tabcft
git new line

分支管理策略

  1. 一般在个人分支或者特性分支上进行开发
  2. 开发完成后, 合并到dev分支
  3. 然后测试或开发leader把代码合并到test分支
  4. test分支进行了充分测试后, 合并到master分支
  5. master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活
  6. 合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

临时切换到其他分支去修复bug, 怎么暂存git stash当前的工作内容

当你接到一个修复一个代号110的bug的任务时,很自然地,你想创建一个分支bug-110来修复它,但是当前正在dev上进行的工作还没有提交:

# shell $> git status
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   new.php

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   readme.md

并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?

幸好,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

# shell $> git stash
Saved working directory and index state WIP on dev: c5dc73a add merge

现在,用git status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。

首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支:

# shell $> git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
  (use "git push" to publish your local commits)

# shell $> git checkout -b bug-110
Switched to a new branch 'bug-110'

现在修复bug,需要把“Git is free software …”改为“Git is a free software …”,然后提交:

# shell $> git add readme.md 
# shell $> git commit -m "fix bug 110"
[bug-110 7d613e2] fix bug 110
 1 file changed, 1 insertion(+), 1 deletion(-)

修复完成后,切换到master分支,并完成合并,最后删除bug-110分支:

# shell $> git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
  (use "git push" to publish your local commits)

# shell $> git merge --no-ff -m "merged bug fix 110" bug-110
Merge made by the 'recursive' strategy.
 readme.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

现在可以再次回到dev分支继续干活了!

# shell $> git checkout dev
Switched to branch 'dev'

# shell $> git status
On branch dev
nothing to commit, working tree clean

工作区是干净的,刚才的工作现场存到哪去了?用git stash list命令看看:

# shell $> git stash list
stash@{0}: WIP on dev: c5dc73a add merge

工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法: > 方法1: git stash apply恢复后,使用git stash drop来删除;
> 方法2: git stash pop,恢复的同时把stash内容也删除;

# shell $> git stash pop
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   new.php

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   readme.md

Dropped refs/stash@{0} (35d66e2ee266f39ea296182fb2354265b91b432d)

再用git stash list查看,就看不到任何stash内容了:

# shell $> git stash list

你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:

# shell $> git stash apply stash@{0}

多人协作的工作模式

  • 首先,使用git push origin <branch-name>推送自己的修改;
  • 如果推送失败,则说明远程分支有更新,你需要先用git pull进行合并;
  • 如果合并有冲突,则需要先解决冲突,并在本地进行提交;
  • 如果没有冲突或者解决掉冲突后,再使用git push origin <branch-name>推送;
  • 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,需用命令git branch --set-upstream-to <branch-name> origin/<branch-name>建立远程分支的关联.

rebase

  • rebase操作可以把本地未push的分叉提交历史整理成直线;
  • rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

原文地址

https://www.liaoyongfu.com/2018/08/94c6bcb0-9607-11e8-948c-f927d580c3cf/

评论