git branch
git checkout -b
git branch -d
git merge,解决冲突
git stash

分支


git init自动创建的本地 master 分支怎么查看

查看分支 git branch

git branch: 查看分支,带*的表示当前所在分支

monkey_jerry@DESKTOP-6B5D8GA MINGW64 /f/gitTest (master)
$ git branch
* master

分支管理

原则上讲,我们不在 master 分支上干活,master 分支保持最稳定,用于发布新版本。因此我们需要新的分支,如在 dev 分支上干活,在 bug 分支上修复 bug,在 feature 分支上做一些新的 feature,等等。

git workflow

创建分支 / 切换分支

  • git checkout -b : 创建分支并切换到创建的分支
    如创建 dev 分支并切换到 dev 分支
$ git checkout -b dev
Switched to a new branch 'dev'
M       readme.txt

$ git branch
* dev
  master

note:git checkout -b <branchname>相当于创建分支git branch <branchname>切换分支git checkout <branchname>

$ git branch
* master

$ git branch dev
$ git branch
  dev
* master
$ git checkout dev
Switched to branch 'dev'
M       readme.txt
$ git branch
* dev
  master

删除分支

  • git branch -d : 删除分支
$ git branch
* dev
  master

# 在当前分支上工作时不能删除当前分支
$ git branch -d dev
error: Cannot delete branch 'dev' checked out at 'F:/gitTest'

$ git checkout master
Switched to branch 'master'
M       readme.txt

$ git branch -d dev
Deleted branch dev (was 7e20f91).

$ git branch
* master

note: 无法删除当前正在工作的分支,需切换到其他分支才能删除。

  • git branch -D : 强行删除一个没有合并merge过的分支
    当一个分支还没合并,产品经理要改需求,需要砍掉,这个时候就要删除这个分支,就要使用-D参数删除。
$ git checkout -b feature
Switched to a new branch 'feature'
$ git branch
* feature
  master

$ touch newfeature.txt
$ git add newfeature.txt
$ git status
On branch feature
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   newfeature.txt
$ git commit -m 'add new feature'
[feature a31818d] add new feature
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 newfeature.txt

$ git checkout master
Switched to branch 'master'
$ git branch
  feature
* master

# 未合并的分支可使用-D强制删除
$ git branch -d feature
error: The branch 'feature' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature'.
$ git branch -D feature
Deleted branch feature (was a31818d).

合并分支

我们在本地 dev 分支工作完成后 (修改或者新增了文件),会向 master 分支合并即merge代码。

  • git merge :合并分支到当前工作分支
$ git branch
* master
$ git checkout -b dev
Switched to a new branch 'dev'
$ git branch
* dev
  master
$ git status
On branch dev
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.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git add .
$ git commit -m 'add a line on branch dev'
[dev f184c1c] add a line on branch dev
 1 file changed, 2 insertions(+), 1 deletion(-)
$ git checkout master
Switched to branch 'master'
$ git status
On branch master
nothing to commit, working tree clean

$ git merge dev
Updating d684f26..f184c1c
Fast-forward
 readme.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
$ git status
On branch master
nothing to commit, working tree clean
$ cat readme.txt
a readme file
add a line on branch dev

note: merge分支需要切换分支到需要合并到的分支即git merge <branchname>为合并分支到当前工作分支
note: 注意merge打印的信息,我们可以看到有Fast-forward,这个有什么特殊含义呢,显然这种合并方式是默认方式。

合并方式

  • git log --graph --pretty=oneline --abbrev-commit:查看分支合并图
  • git merge --no-ff -m :no-ff 方式合并
  1. ff 方式合并
$ git log --graph --pretty=oneline --abbrev-commit
* 34aeeda (HEAD -> master, dev) hello monkeyjerry
* f42d59d add hello.py
  1. no-ff 方式合并
git merge --no-ff -m 'no-ff' dev
Merge made by the 'recursive' strategy.
 hello.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

$ git log --graph --pretty=oneline --abbrev-commit
- 95311c2 (HEAD -> master) Merge branch 'dev'
|\
| * b670bb9 (dev) no-ff
|/
* 34aeeda hello monkeyjerry
* f42d59d add hello.py


显然,no-ff 可以清楚看清分支上的代码改动,一般个工作中都采用这种方式合并

合并冲突

合并时难免会出现冲突,工作中,如同事和你同时修改了同一行,如果他的提交先于你,当你提交的时候,则会产生冲突,此时就必须解决冲突后,你才能正常提交。
这里举例如下:dev 分支修改某一行后,然后修改了 master 分支(模拟同事修改了某一行并先于你提交),在 master 分支合并 dev 分支则会出现冲突。

monkey_jerry@DESKTOP-6B5D8GA MINGW64 /f/gitTest (dev)
$ git commit -m 'and simple'
[dev 3ec8f83] and simple
 1 file changed, 1 insertion(+), 1 deletion(-)
-------------------------------------------------------
monkey_jerry@DESKTOP-6B5D8GA MINGW64 /f/gitTest (master)
$ git commit -m '& simple'
[master 627dbcf] & simple
 1 file changed, 1 insertion(+), 1 deletion(-)
-------------------------------------------------------
monkey_jerry@DESKTOP-6B5D8GA MINGW64 /f/gitTest (master)
$ git merge dev
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

monkey_jerry@DESKTOP-6B5D8GA MINGW64 /f/gitTest (master|MERGING)
$ cat readme.txt
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick and simple.
>>>>>>> dev

如上,则在合并时出现了冲突,查看此时的 readme 文件,<<<<<<< HEAD表示当前工作分支内容,>>>>>>> dev表示 dev 分支内容。
手动解决分支,如最终需要保留的版本为 Creating a new branch is quick and simple. 然后在 add,commit 即可。

monkey_jerry@DESKTOP-6B5D8GA MINGW64 /f/gitTest (master|MERGING)
$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")

monkey_jerry@DESKTOP-6B5D8GA MINGW64 /f/gitTest (master|MERGING)
$ git add .

monkey_jerry@DESKTOP-6B5D8GA MINGW64 /f/gitTest (master|MERGING)
$ git commit -m 'fix conflict'
[master 25b02ce] fix conflict

保存现场 git stash

如有这样一个场景:突然有紧急的 bug 需要修复,显然我们可以拉一个 bug 分支出来改 bug,但手头的活才干了一半怎么办?那就可以用git stash把这个现场存储起来,等我修复完 bug 后,再恢复现场继续工作即可。

  • git stash: 保存现场,可保存多个
  • git stash pop: 恢复现场,恢复的同时且删除保存的 stash 内容
$ git status
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   feature.py

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:   feature.py
# 保存现场
$ git stash
Saved working directory and index state WIP on dev: 427d964 hello world
$ git checkout -b bugfix
Switched to a new branch 'bugfix'
$ ls
hello.py
# 修复bug后切换会dev分支继续干活
$ git checkout dev
Switched to branch 'dev'
# 恢复现场
$ git stash pop
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   feature.py

Dropped refs/stash@{0} (9cb4c8d209db9e8fdd97528c715842a59dca8345)
# feature.py恢复了
$ ls
feature.py  hello.py
  • git stash list: 查看保存现场的栈
  • git stash apply : 恢复保存的现场,但不删除保存的 stash 内容

这里不做进一步演示,后面我们会采用可视化界面,操作起来将更方便