这有点奇怪,但我无法用git完成一个非常常见的操作。基本上我想要的是签出一个功能分支,而不是使用它的头但使用SHA id。此SHA指向主分支的合并。
问题是我得到的只是master分支而没有来自feature分支的提交。 目前我正在尝试修复之前在master分支中引入的回归。
为了更具描述性,我制作了一个小的bash脚本来重新创建问题存储库:
#!/bin/bash
rm -rf ./.git
git init
echo "test1" > test1.txt
git add test1.txt
git commit -m "test1" -a
git checkout -b patches master
echo "test2" > test2.txt
git add test2.txt
git commit -m "test2" -a
git checkout master
echo "test3" > test3.txt
git add test3.txt
git commit -m "test3" -a
echo "test4" > test4.txt
git add test4.txt
git commit -m "test4" -a
echo "test5" > test5.txt
git add test5.txt
git commit -m "test5" -a
git checkout patches
git merge master
#Now how to get a branch having all commits from patches + test3.txt + test4.txt - test5.txt ???
基本上我想要的只是用文件1-4签出分支“补丁”,但不包括test5.txt。
操作:
git checkout [sha_where_test4.txt_entered]
...只是给出一个包含test1,test3,test4的分支,但不包括test2.txt
更复杂的例子:
#!/bin/bash
rm -rf ./.git
git init
echo "test1" > test1.txt
git add test1.txt
git commit -m "test1" -a
git checkout -b patches master
echo "test2" > test2.txt
git add test2.txt
git commit -m "test2" -a
git checkout master
echo "test3" > test3.txt
git add test3.txt
git commit -m "test3" -a
echo "test4" > test4.txt
git add test4.txt
git commit -m "test4" -a
echo "test5" > test5.txt
git add test5.txt
git commit -m "test5" -a
git checkout patches
git merge master
echo "test6" > test6.txt
git add test6.txt
git commit -m "test6" -a
#Now how to get a branch having all commits from patches + test3.txt + test4.txt - test5.txt ???
git log --topo-order | cat
# Now I need something to help me going back to history
# without manually calculating that patches~2 sha's
git checkout -b patches.tmp master~1
git merge patches~2
感谢。
答案 0 :(得分:1)
没有这样的观点。这里有两个并行的开发路径,一个包含文件test1和test2,另一个包含文件test1,test3,test4和test5。但是,您可以使用合并创建这样的点。
检查SHA1以查找添加test4的提交,并与添加test2的提交合并。例如,在运行脚本后,我的存储库看起来像这样:
* b054987 (HEAD, patches) Merge branch 'master' into patches
|\
* | 5ae790f test2
| * f2a3dac (master) test5
| * 70e8cd2 test4
| * c4102ed test3
|/
* d448eaa test1
在此,运行:
% git checkout 70e8c
% git merge 5ae79
结果是包含文件1-4的HEAD:
* bcc8f7a (HEAD) Merge commit '5ae79' into HEAD
|\
| | * b054987 (patches) Merge branch 'master' into patches
| | |\
| |/ /
| * | 5ae790f test2
| | * f2a3dac (master) test5
| |/
|/|
* | 70e8cd2 test4
* | c4102ed test3
|/
* d448eaa test1
% ls
test1.txt test2.txt test3.txt test4.txt
您现在可以从这一点创建分支。
答案 1 :(得分:1)
关于你的第一个例子,你需要在test2之上重播test3和4:这是一个经典的case of rebase --onto
:
从:
开始alt text http://img169.imageshack.us/img169/2255/gitr1.png
标记当前的补丁安置,并将补丁分支移动到您想要结束的地方(test4):
C:\Prog\Git\tests\rep\main>git checkout patches
Switched to branch 'patches'
C:\Prog\Git\tests\rep\main>git checkout -b tmp
Switched to a new branch 'tmp'
C:\Prog\Git\tests\rep\main>git checkout patches
Switched to branch 'patches'
C:\Prog\Git\tests\rep\main>git reset --hard master~1
HEAD is now at 8448d0f test4
这会给你:
alt text http://img169.imageshack.us/img169/4826/gitr2.png
只需重新定义你想要的正确提交顺序:
C:\Prog\Git\tests\rep\main>git checkout tmp
Switched to branch 'tmp'
C:\Prog\Git\tests\rep\main>git rebase --onto tmp tmp~1 patches
First, rewinding head to replay your work on top of it...
Applying: test3
Applying: test4
给出了:
alt text http://img52.imageshack.us/img52/372/gitr3.png
仅适用于要移动的线性提交集。
答案 2 :(得分:0)
git merge
操作不会返回并更改历史记录,而是创建一个新提交,指向它来自的两个历史记录。所以,在图片中,你所拥有的是这样的:
2-----------\ / \ 1---3---4---5---M (HEAD)
当您回溯历史记录以返回修订版4时,您将获得文件1,3和4,但不是 2。