4

这有点奇怪,但我无法用 git 完成一个非常常见的操作。基本上我想要的是检查一个功能分支,而不是使用它的头部,而是使用 SHA id。此 SHA 指向来自 master 分支的合并。

问题是我得到的只是主分支,没有来自功能分支的提交。目前我正在尝试修复之前在 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

谢谢。

4

3 回答 3

1

没有这样的观点。您在这里有两条并行的开发路径,一条包含文件 test1 和 test2,另一个包含文件 test1、test3、test4 和 test5。不过,您可以通过合并创建这样的点。

查看添加 test4 的提交的 SHA1,并与添加 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

您现在可以从您喜欢的这一点创建一个分支。

于 2010-03-14T18:58:58.420 回答
1

关于您的第一个示例,您需要在 test2 之上重播 test3 和 4:这是一个经典案例rebase --onto

从...开始:

替代文字 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

这给了你:

替代文字 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

这使:

替代文字 http://img52.imageshack.us/img52/372/gitr3.png

这仅适用于要移动的线性提交集。

于 2010-03-14T19:59:42.163 回答
0

git merge操作不会返回并更改历史记录,而是创建一个指向它来自的两个历史记录的新提交。所以,在图片中,你所拥有的是这样的:

  2------------\
 / \
1---3---4---5---M(头部)

当您倒回历史记录以返回修订版 4 时,您会得到文件 1、3 和 4,但不会得到文件2。

于 2010-03-14T18:56:03.210 回答