分支管理
就是多人项目每个人都有自己的分支,然后都在不同的分支干活,分支是一开始都是从原分支产生,然后经过修改每个人的都不同,开发完毕再一起合并到原来的分支上。相当于漫威的平行宇宙的主宇宙和其他宇宙,不过他们的是可能除了穿越互不影响,Git的是最后再合并到一起,像是道家的道生一,一生二,二生三,三生万物,然后万物归一这样,不过也可以区别的分支去看(切换)。
其他控制系统SVN也有分支管理,不过创建的慢,切换也慢,基本成了摆设。而Git能在1秒钟之内完成
创建dev分支
之后的延长都是在dev之后延长
这个是合并
这样我们创建切换到dev
$ git checkout -b dev
Switched to a new branch 'dev'
-b 相当于创建并切换
就是这两个
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
然后用命令查看当前分支 会有所有命令 *号是当前命令
$ git branch
* dev
master
然后修改之前的ReadMe.txt然后提交
$ git add ReadMe.txt
$ git commit -m "branch test"
[dev 486ad0c] branch test
1 file changed, 2 insertions(+), 1 deletion(-)
现在是提交到dev分支上,之后切换到master分支上,
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
然后再看ReadMe之前添加的消失了
因为之前的修改在dev上
下来我们把dev分支合并到master上
$ git merge dev
Updating 42158b4..486ad0c
Fast-forward
ReadMe.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
然后再看ReadMe.txt发现文件内容一样了
上面Fast-forward是快速合并,并不是每次合成都能用快速合成,所以后面会提别的合并模式。
然后可以放心删除dev分支了
$ git branch -d dev
Deleted branch dev (was 486ad0c).
然后再查看分支,只剩下master了
$ git branch
* master
解决冲突
再来创建一个分支
$ git checkout -b featurel
Switched to a new branch 'featurel'
然后修改第二行改为之前不同的东西
$ git add ReadMe.txt
$ git commit -m "AND simple"
[featurel 780d295] AND simple
1 file changed, 1 insertion(+), 1 deletion(-)
切换到master
$ 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)
系统提示当前分支比master还要超前一个提交
我们再打开ReadMe.txt把最后一行胡乱改了提交
$ git add ReadMe.txt
$ git commit -m '& simple'
[master cedd95d] & simple
1 file changed, 1 insertion(+), 1 deletion(-)
现在就成了这样子 开始有分岔路口了
这样git就无法快速合并,就会有冲突.
$ git merge featurel
Auto-merging ReadMe.txt
CONFLICT (content): Merge conflict in ReadMe.txt
Automatic merge failed; fix conflicts and then commit the result.
告诉我们冲突了要自己手动解决冲突
查看状态
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add ..." to mark resolution)
both modified: ReadMe.txt
Untracked files:
(use "git add ..." to include in what will be committed)
gitskills/
no changes added to commit (use "git add" and/or "git commit -a")
然后打开我们的ReadMe.txt发现有奇怪的符号
Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容
选择一个分支的内容留下来
然后提交
$ git add ReadMe.txt
$ git commit -m 'conflict fixed'
[master 026222f] conflict fixed
打印日志,可以看到 合并情况
$ git log
commit 026222f9d7a330f14e27e5327c260c3becea8338 (HEAD -> master)
Merge: cedd95d 780d295
Author: Corn <[email protected]>
Date: Mon Jun 3 22:02:40 2019 +0800
conflict fixed
commit cedd95dfaed49fbb93cdb7777ac2dbbf60170228
Author: Corn <[email protected]>
Date: Mon Jun 3 21:52:29 2019 +0800
& simple
commit 780d2958c60842523dfa7303661dc511cf0d3e38 (featurel)
Author: Corn <[email protected]>
Date: Mon Jun 3 21:47:10 2019 +0800
AND simple
commit 486ad0c16b9e723f4819ba84f9eda7948a9b647f
Author: Corn <[email protected]>
Date: Mon Jun 3 21:33:57 2019 +0800
然后这个log只能看大概还有自己的注释
我想看详细的然后就出不去了,成了打印日志
之后不管怎么输入都是这一条
fatal: not a git repository (or any of the parent directories): .git
解决方法用这个指令添加一下就行了
$ git init
Initialized empty Git repository in C:/Users/Administrator/Desktop/.git/
然后切换查看咱们的目录
$ cd learngit
$ pwd
/c/Users/Administrator/Desktop/learngit
这样是详细查看合并
$ git log --graph --pretty=oneline --abbrev-commit
* 026222f (HEAD -> master) conflict fixed
|\
| * 780d295 AND simple
* | cedd95d & simple
|/
* 486ad0c branch test
* 42158b4 (origin/master) change
* 783b9ec readMeFile
下来是删除分支
$ git branch -d featurel
Deleted branch featurel (was 780d295).
所以说冲突了只能自己手动取舍
分支管理策略
之前说了合并分支时git会用Fast forward模式,但是合并后没有合并信息,所以之后查看就看不到有过合并。禁用Fast forward,Git会在merge时生成一个新的commit这样就可以在分支历史上看出分支信息。
创建并切换分支
$ git checkout -b dev
Switched to a new branch 'dev'
M ReadMe.txt
修改ReadMe
提交
$ git add ReadMe.txt
$ git commit -m 'add merge'
[dev df631c3] add merge
1 file changed, 1 insertion(+), 1 deletion(-)
切换到master分支
$ git checkout master
Switched to branch 'master'
合并dev分支 用--no-ff参数禁用 FastForward
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
$ git merge --no-ff -m 'merge with no-ff' dev
Merge made by the 'recursive' strategy.
ReadMe.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --graph --pretty=oneline --abbrev-commit
* c654445 (HEAD -> master) merge with no-ff
|\
| * df631c3 (dev) add merge
|/
* 026222f conflict fixed
|\
| * 780d295 AND simple
* | cedd95d & simple
|/
* 486ad0c branch test
* 42158b4 (origin/master) change
* 783b9ec readMeFile
Bug分支
BUG可以用新的临时分支来修复,修复后,合并分支,然后将临时分支删除
切换到dev 把bug文件加入
$ git checkout dev
Switched to branch 'dev'
$ git add hello.cs
$ git status
On branch dev
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: hello.cs
Untracked files:
(use "git add ..." to include in what will be committed)
gitskills/
但是你现在的东西没有完工需要一天,这个BUG要2小时之内修复。然后就用到stash功能,把当前工作现场储存,等恢复现场后继续工作。
$ git stash
Saved working directory and index state WIP on dev: df631c3 add merge
然后查看状态会发现工作区是干净的
$ git status
On branch dev
Untracked files:
(use "git add ..." to include in what will be committed)
gitskills/
nothing added to commit but untracked files present (use "git add" to track)
然后确定需要在哪个分支上修复BUG,假定在master上,
$ 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)
$ git checkout -b issue-101
Switched to a new branch 'issue-101'
然后修复BUG 添加一个新的吧
$ git add ReadMe.txt
$ git commit -m 'fix bug 101'
[issue-101 57306ec] fix bug 101
1 file changed, 2 insertions(+), 1 deletion(-)
然后修复完毕 切换到master分支然后删除 issue-101分支
$ 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)
$ git merge --no-ff -m 'merged bug fix 101' issue-101
Merge made by the 'recursive' strategy.
ReadMe.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
切换到dev查看状态发现是空的
$ git checkout dev
Switched to branch 'dev'
$ git status
On branch dev
Untracked files:
(use "git add ..." to include in what will be committed)
gitskills/
nothing added to commit but untracked files present (use "git add" to track)
查询刚才把工作内容存哪里了
$ git stash list
stash@{0}: WIP on dev: df631c3 add merge
怎么恢复呢
1.git stash apply用这个恢复stash历史储存不会删除,之后要删除要用git stash drop。
2.git stash pop这两个直接都删除了
$ git stash pop
On branch dev
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: hello.cs
Untracked files:
(use "git add ..." to include in what will be committed)
gitskills/
Dropped refs/stash@{0} (cf4e502227c678adba0cc996e3066bb01254c9f8)
$ git stash list
然后就真空了
当然可能我们不只有一个stash
但有很多个想恢复其中某一个时
用git stash list
用这个函数恢复想要恢复的第几个
$ git stash apply stash@{0}
Feature分支
当开发项目需要有新功能添加
因为是边试边加,不想把主分支搞乱了,可以用feature分支,开发完成合并再删除
比如我们现在开发vulcan
$ git checkout -b feature-vulcan
Switched to a new branch 'feature-vulcan'
开发完毕之后
$ git add hello.cs
$ git status
On branch feature-vulcan
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: hello.cs
Untracked files:
(use "git add ..." to include in what will be committed)
gitskills/
切换到dev
$ git checkout dev
然后发现经费不足,功能取消要销毁
$ git branch -d feature-vulcan
Deleted branch feature-vulcan (was df631c3).
穆老师的有-d之后会提示没有合并提示-D强制销毁,但是我们这里的没有
多人协作
之前从远程仓库克隆的时候会自动把本地master分支和远程master分支对应起来,默认仓库名字是origin
查看远程库信息
$ git remote
origin
查看远程库详细信息 如果没有权限看不到push地址
$ git remote -v
origin [email protected]:1004019267/learngit.git (fetch)
origin [email protected]:1004019267/learngit.git (push)
1.推送
那么如何推送分支到远程库呢?
这样就推送上去了
$ git push origin master
Enumerating objects: 22, done.
Counting objects: 100% (22/22), done.
Delta compression using up to 4 threads
Compressing objects: 100% (8/8), done.
Writing objects: 100% (20/20), 1.47 KiB | 251.00 KiB/s, done.
Total 20 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), done.
To github.com:1004019267/learngit.git
42158b4..173a552 master -> master
再推送一下dev分支吧
$ git push origin dev
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'dev' on GitHub by visiting:
remote: https://github.com/1004019267/learngit/pull/new/dev
remote:
To github.com:1004019267/learngit.git
* [new branch] dev -> dev
但是有一些分支是不需要的
master主分支需要时刻与远程同步
dev开发分支 成员都在这工作,所以也要远程同步
bug分支只用在本地就行了
feature如果你和别人一起开发就需要远程同步了
2.抓取分支
就是如何别人下载你的分支 需要添加SSH Key到GitHub
但是练习就在一个电脑不同目录下算了
找到你的信息 粘贴下来
然后再不同的目录右键
$ git clone [email protected]:1004019267/learngit.git
Cloning into 'learngit'...
remote: Enumerating objects: 26, done.
remote: Counting objects: 100% (26/26), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 26 (delta 3), reused 26 (delta 3), pack-reused 0
Receiving objects: 100% (26/26), done.
Resolving deltas: 100% (3/3), done.
因为是克隆的 所以只能看到本地的master分支
$ git branch
* master
想要在dev分支开发就需要把远程dev分支到本地
$ git checkout -b dev origin
Switched to a new branch 'dev'
Branch 'dev' set up to track remote branch 'master' from 'origin'.
然后添加提交就可以了
$ git add abc.txt
$ git commit -m 'add abc'
[dev 14e9e2e] add abc
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 abc.txt
$ git push origin dev
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 261 bytes | 261.00 KiB/s, done.
Total 3 (delta 0), reused 1 (delta 0)
To github.com:1004019267/learngit.git
df631c3..14e9e2e dev -> dev
然后回到一开始的那个文件夹 ,你也修改了这个abc文件
$ cat abc.txt
12312
你把他提交推送上去 报错了 因为有冲突
$ git add abc.txt
$ git commit -m 'add new abc'
[dev 9541648] add new abc
2 files changed, 1 insertion(+)
create mode 100644 abc.txt
create mode 100644 hello.cs
$ git push origin dev
To github.com:1004019267/learngit.git
! [rejected] dev -> dev (fetch first)
error: failed to push some refs to '[email protected]:1004019267/learngit.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
git 提示我们git pull把最新的dev抓下来本地合并在提交 然后也挂了
$ git pull
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:1004019267/learngit
df631c3..14e9e2e dev -> origin/dev
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/ dev
因为没有指定本地dev和远程dev分支连接 根据提示
$ git branch --set-upstream-to=origin/dev dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
然后再pull
$ git pull
然你输入问什么要合并dev
我走不出来就关了 然后再
如果有冲突记得解决冲突和之前说的一样手动二选一
$ git push origin dev
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 619 bytes | 619.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To github.com:1004019267/learngit.git
14e9e2e..c83d1f5 dev -> dev
然后GitHub上就有了
Rebase(基变)
切换到master分支
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
查看一下之前的提交远程库线路 每次提交后push的必须先pull,在本地合并,然后才能push。
然后提交历史很多分叉比较乱
rebase让提交历史变成一条直线
参考是这个文章
https://www.cnblogs.com/pinefantasy/articles/6287147.html
master分支什么也没有 加入一个相同的abc.txt
对了这里有个 如果是git log 查看会导致退不出就按Q就可以了
然后添加我打印的丢失了不过不影响
git add abc.txt
git commit -m 'master abc.txt'
打印日志 发现
$ git log --graph --pretty=oneline --abbrev-commit
* e554b23 (HEAD -> master) add master abc
* 173a552 (origin/master) merged bug fix 101
|\
| * 57306ec (issue-101) fix bug 101
|/
* c654445 merge with no-ff
|\
| * df631c3 add merge
|/
* 026222f conflict fixed
|\
| * 780d295 AND simple
* | cedd95d & simple
|/
* 486ad0c branch test
* 42158b4 change
* 783b9ec readMeFile
注意这两行 相当于不同版本的添加
- e554b23 (HEAD -> master) add master abc
- 173a552 (origin/master) merged bug fix 101
上传
$ git push origin master
调用这个命令
$ git rebase
First, rewinding head to replay your work on top of it...
Fast-forwarded master to refs/remotes/origin/master.
远程的竟然合并了
$ git log --graph --pretty=oneline --abbrev-commit
* e554b23 (HEAD -> master, origin/master) add master abc
* 173a552 merged bug fix 101
|\
| * 57306ec (issue-101) fix bug 101
|/
* c654445 merge with no-ff
|\
| * df631c3 add merge
|/
* 026222f conflict fixed
|\
| * 780d295 AND simple
* | cedd95d & simple
|/
* 486ad0c branch test
* 42158b4 change
* 783b9ec readMeFile
切换到dev
查看log 发现提交的分支的log都合并成了一条
$ git checkout dev
Switched to branch 'dev'
Your branch is up to date with 'origin/dev'.
$ git log --graph --pretty=oneline --abbrev-commit
* c83d1f5 (HEAD -> dev, origin/dev) Merge branch 'dev' of github.com:1004019267/learngit into dev
|\
| * 14e9e2e add abc
| * 173a552 merged bug fix 101
| |\
| | * 57306ec (issue-101) fix bug 101
| |/
| * c654445 merge with no-ff
| |\
* | | 9541648 add new abc
| |/
|/|
* | df631c3 add merge
|/
* 026222f conflict fixed
|\
| * 780d295 AND simple
* | cedd95d & simple
|/
* 486ad0c branch test
* 42158b4 change
* 783b9ec readMeFile
这样的好处是5个人5个人分支不同的log记录这样合并成了一个方便最终版本查看,变基操作只需要提交者变就可以了
这是变基之后的样子,后面打印时候就成这样了 前面的不算变基成功 没有了符号分支这样
$ git log --pretty=oneline --abbrev-commit
e554b23 (HEAD -> master, tag: v1.0, origin/master) add master abc
173a552 merged bug fix 101
57306ec (issue-101) fix bug 101
c654445 merge with no-ff
df631c3 add merge
026222f conflict fixed
cedd95d & simple
780d295 AND simple
486ad0c branch test
42158b4 change
783b9ec readMeFile