使用replace命令实现被拆分的分支的重新合并
如果想把当前工作的分支拆分成两个仓库,一个保留大部分历史,另外一个保存最新状态,可以使用replace命令。比如,我们有一个存在5个提交的分支:
$ git log --oneline
2675f7d (HEAD -> master) 5th commit
3a67cda 4th commit
a965d59 3rd commit
965600c 2nd commit
ee6a085 1st commit
将它拆分为两个仓库,第一个包含第一次到第四次提交,第二个只包含第四第五个提交。使用branch命令,以第四个提交为基础生成一个名字为history的分支:
$ git branch history 3a67cda
$ git log --oneline --decorate
2675f7d (HEAD -> master) 5th commit
3a67cda (history) 4th commit
a965d59 3rd commit
965600c 2nd commit
ee6a085 1st commit
将新的分支推送到远程仓库。推送到远程仓库有个前提,就是远程的仓库已经被建立。就算是空的也可以。
$ git remote add project-history https://github.com/kutilion/project-history
$ git push project-history history:master
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (12/12), 882 bytes | 98.00 KiB/s, done.
Total 12 (delta 0), reused 0 (delta 0)
切换回master分支,确认一下提交信息
$ git log --oneline --decorate
2675f7d (HEAD -> master) 5th commit
3a67cda (project-history/master, history) 4th commit
a965d59 3rd commit
965600c 2nd commit
ee6a085 1st commit
可以看到,master分支还是5个提交,但是history分支只有4个提交。
这样,一个保留大部分历史的history分支就被在远端仓库中发布了。 下面来看看如何建立只保存较新提交的分支。
使用commit-tree命令创建一个平行于master分支第三次提交的基础分支
$ echo 'get history' | git commit-tree a965d59^{tree}
7def9a6f6bbd26ef183821ffa29142a12bad94f0
使用变基,将master的第四第五提交变基到这个新建立的分支上
$ git rebase --onto 7def9a6f a965d59
First, rewinding head to replay your work on top of it...
Applying: 4th commit
Applying: 5th commit
注意,变基的第一个参数是刚才建立的新分支,第二个参数是master分支的第三个提交。
确认一下当前分支的状态,变基后master分支只有三个提交,最初的是commit-tree做成的,后两个是变基过来的原master分支的第四第五提交。
$ git log --oneline
1d8b05c (HEAD -> master) 5th commit
10b9948 4th commit
7def9a6 get history
这样,一个较新的干净的新分支就建立了。现在将这个新的分支推送到远程仓库。
$ git remote add project https://github.com/kutilion/project
$ git push project master:master
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (9/9), 701 bytes | 175.00 KiB/s, done.
Total 9 (delta 0), reused 0 (delta 0)
To https://github.com/kutilion/project
* [new branch] master -> master
下面为了模拟想要获取全部历史的人来克隆远程仓库,我把本地的工程删除。使用clone命令来从远程仓库拉取工程。拉取较新仓库(project工程)后,需要添加历史仓库(project-history工程)并且获取历史。
$ git clone https://github.com/kutilion/project
Cloning into 'project'...
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 9 (delta 0), reused 9 (delta 0), pack-reused 0
Unpacking objects: 100% (9/9), done.
$ cd project
$ git log --oneline
1d8b05c (HEAD -> master, origin/master, origin/HEAD) 5th commit
10b9948 4th commit
7def9a6 get history
$ git remote add project-history https://github.com/kutilion/project-history
$ git fetch project-history
warning: no common commits
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 12 (delta 0), reused 12 (delta 0), pack-reused 0
Unpacking objects: 100% (12/12), done.
From https://github.com/kutilion/project-history
* [new branch] master -> project-history/master
现在,master 分支中拥有最近的提交并且在 project-history/master 分支中拥有过去的提交。
$ git log --oneline master
1d8b05c (HEAD -> master, origin/master, origin/HEAD) 5th commit
10b9948 4th commit
7def9a6 get history
$ git log --oneline project-history/master
3a67cda (project-history/master) 4th commit
a965d59 3rd commit
965600c 2nd commit
ee6a085 1st commit
为了将它们合并为一个分支,可以使用replace命令,注意两个参数的提交,都指向了4th commit。
$ git replace 10b9948 3a67cda
查看当前master分支状态
$ git log --oneline master
1d8b05c (HEAD -> master, origin/master, origin/HEAD) 5th commit
10b9948 (replaced) 4th commit
a965d59 3rd commit
965600c 2nd commit
ee6a085 1st commit