如何在Git中保持分支层次结构?

4

简单来说,我创建了一个像这样的git分支结构:

enter image description here

生成自:

git init
echo "Hello World" > file1.txt
git add file1.txt
git commit -m "Hello world"
git checkout -b A
echo "This is from A branch" > file2.txt
git add file2.txt
git commit -m "from A branch"
git checkout -b B
echo "This is from B branch" >> file2.txt
git commit -a -m "from B branch"

现在,我克隆这个结构并同步主分支masterA 分支和 B 分支:
git clone /path-to-source/
git checkout -b master remotes/origin/master
git checkout -b A remotes/origin/A

克隆的代码库反映了源代码的层次结构:

enter image description here

现在我回到源文件夹,并在主分支中添加一些内容,然后重新设置 A 和 B 的基础:

cd /path-to-source/
git checkout master
echo "more files" > file3.txt
git add file3.txt
git commit -m "Improved master"
git checkout A
git rebase master
git checkout B
git rebase A

enter image description here

问题出现在我回到克隆的存储库并尝试保持这个结构时。如果我只是拉取master分支,我会得到如下结果:

enter image description here

我可以去每个分支更新:

git checkout A
git pull

但我得到的分支树长这样:

enter image description here

问题是,如何保持干净的仓库克隆?也就是说,我想在克隆的仓库中获得这个(操作过的)图形:

enter image description here

奖励: 如果可能的话,我希望找到一种方法来保留在AB分支中的提交记录,如下所示:

enter image description here

从源代码库中生成这些命令:

git checkout A
echo "something" > other.txt
git add other.txt
git commit -m "Other A commit"
git checkout B
git rebase A

注意1:如果有帮助的话,克隆的存储库从不提交 注意2:您可以假设只有一个用户对源存储库进行提交


不是百分之百确定,但如果非检出分支设置为跟踪远程分支(请阅读git branch或git checkout的手册以了解更多关于跟踪分支的信息),则拉取应该可以在其上工作。 - Nevik Rehnel
可能吧,但我需要在已经检出的分支中进行操作(分支层次在我的项目中很重要)。 - Ivan
3
总体说明:一旦提交内容发布,请勿进行变基操作。(注:变基操作指更改Git提交历史记录的操作,可能会导致其他开发人员在合并代码时产生困难。) - poke
1个回答

5
重新定位基准点意味着更改SHA1,因此您克隆中的分支A不再有效。
您可以参考“如何在其他人推送重定位或重置到发布的分支后恢复/同步化?”来恢复克隆的分支A(灵感来自“从上游重定位中恢复”部分)。
但是如果:
- 这些重定位是经常发生的, - 您在分支A和分支B的克隆中没有任何新提交,
您可能只想根据它们的origin/Aorigin/B重置这些分支(在克隆中):将分支A HEAD重置为origin/A
git branch -f origin/A

为什么“如果这些变基经常发生”?可能会出现执行问题吗?无论如何,在A分支中的提交很少,但是会发生,想法是将所有这些自动化到一个shell脚本中。感谢您的参考。 - Ivan
1
@Ivan 没有性能问题,只是恢复的方式有点繁琐,仅在您在克隆上的分支中进行了一些提交,并且需要在获取新的 A 历史记录(因为 A 在上游库中已被变基)后在其之上重播时才有用。但是,如果您在克隆中没有对 A 进行任何操作,则解决方案很简单:将您的 A 重置为 origin/A - VonC
1
@Ivan,考虑到你的笔记,git branch -f A origin/A 可能就是你非常简单的自动化操作。 - VonC
完美,它有效。但是一个问题:为什么不用 git checkout A + git rebase origin/A - Ivan
1
@Ivan 因为克隆中的 A 包含与 origin/A 相同的提交(除了 SHA1 不同),所以当重演 Aorigin/A 之上时,rebase 将简单地忽略这些相同的提交。最终结果将与直接将 A HEAD 重置为 origin/A 相同。 - VonC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接