10

git subtree用来组织我的 git 存储库。假设我有一个名为的主存储库repo和一个名为lib.

lib我通过压缩它的历史成功地“导入”了存储库。lib我现在也想通过压缩历史来回馈社会。这似乎不起作用:我指定了--squash选项,git subtree push但是在查看历史记录时,我仍然发送所有提交。

如何重现

这是一个脚本,显示了重现问题所需的最少命令:

#!/bin/bash
rm -rf lib lib-work repo

# repo is the main repository
git init repo
# lib is the 'subtreed' repository (bare to accept pushes)
git init --bare lib

git clone lib lib-work
cd lib-work
# adding a bunch of commits to lib
echo "v1" > README
git add README
git commit -m 'lib commit 1'
echo "v2" > README
git add README
git commit -m 'lib commit 2'
echo "v3" > README
git add README
git commit -m 'lib commit 3'
git push origin master
cd ..

cd repo
# adding initial commit to have a valid HEAD
echo "v1" > README
git add README
git commit -m 'repo commit 1'
git remote add lib ../lib
git subtree add --prefix lib lib master --squash
echo "v4" > lib/README
git add lib/README
git commit -m 'repo commit 2'
echo "v5" > lib/README
git add lib/README
git commit -m 'repo commit 3'
echo "v6" > lib/README
git add lib/README
git commit -m 'repo commit 4'
#git log --all --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s%Creset' --abbrev-commit
# "not working" command :
git subtree push --prefix lib lib master --squash

# pretty print the history
git log --all --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s%Creset' --abbrev-commit
cd ../lib
echo
git log --all --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s%Creset' --abbrev-commit

git log显示问题

这两个git log blabla命令的输出是:

* b075d5e - (HEAD, master) repo commit 4
* ebdc7c7 - repo commit 3
* 9f1edab - repo commit 2
*   3d48bca - Merge commit '34e16a547819da7e228f3add35efe86197d2ddcb' as 'lib'
|\
| * 34e16a5 - Squashed 'lib/' content from commit 2643625
* 3f1490c - repo commit 1
* 1f86fe3 - (lib/master) repo commit 4
* 9f1639a - repo commit 3
* 8bd01bd - repo commit 2
* 2643625 - lib commit 3
* 3d64b8c - lib commit 2
* aba9fcb - lib commit 1

和 :

* 1f86fe3 - (HEAD, master) repo commit 4
* 9f1639a - repo commit 3
* 8bd01bd - repo commit 2
* 2643625 - lib commit 3
* 3d64b8c - lib commit 2
* aba9fcb - lib commit 1

如您所见,"repo commit 2,3,4"尽管我指定了 squash 选项,但 lib 看到了。反过来工作,因此Squashed 'lib/' content from commit f28bf8e.

我在 git 版本 1.8.1.msysgit.1 的 windows 和 git 版本 1.8.3.4 的 linux 上尝试过。

那么为什么这个--squash选项不做壁球呢?

附带问题

为什么 lib/master 会出现在repo存储库的日志中?知道它在“失败”之后出现git push:如果您取消注释第一个git log blabla,您将获得以下输出,显示隐藏的历史但没有 lib/master 的迹象:

* b075d5e - (HEAD, master) repo commit 4
* ebdc7c7 - repo commit 3
* 9f1edab - repo commit 2
*   3d48bca - Merge commit '34e16a547819da7e228f3add35efe86197d2ddcb' as 'lib'
|\
| * 34e16a5 - Squashed 'lib/' content from commit 2643625
* 3f1490c - repo commit 1
4

2 回答 2

9

这可能是 subtree 命令的文档中的错误。

git中的手册指出:

options for 'add', 'merge', 'pull' and 'push'
    --squash              merge subtree changes as a single commit

如果您查看原始子树项目中更多扩展的文档,您会注意到该--squash选项仅针对addand进行了说明merge,因为该功能是针对将内容引入存储库的过程进行描述的。由于pull是合并的一种修改形式,因此也暗示它可以使用--squash.

手册中的push列表没有意义。git subtree push子命令是git subtree split和的组合git push。这意味着--squash应该是一个也支持的选项split,但未split在手册列表中列出。它从未在文档中说明它可以使用--squash.

--squash选项确实被接受split并且push没有错误,但是在对其进行试验之后,它似乎没有任何区别,正如您的示例所述。我的看法是它是错误的,只是被splitandpush命令忽略了。

于 2013-11-22T07:55:35.053 回答
5

现在(Git 2.5,Q2 2015)已​​在官方git subtree文档中确认。

请参阅Danny Lin ( )的提交6ccc71a, 2015 年 5月 7 日。(由Junio C Hamano 合并——提交 6263f58中,2015 年 5 月 22 日)danny0838
gitster

contrib/subtree: 没有push --squash

文档说这--squash是针对 ' add'、' merge'、' pull' 和 ' push',而--squash实际上并没有改变 ' push' 的行为。
更正文档。

--squash:

此选项仅对addmergepull命令有效。


使用 Git 2.29(2020 年第四季度),子树(in contrib/)的文档更加清晰。

请参阅Danny Lin ( ) 的commit ce820cbcommit f99c0c9(2020 年 8 月 18 日(由Junio C Hamano 合并——提交 8923a45中,2020 年 8 月 24 日)danny0838
gitster

contrib/subtree: 文件 ' push' 不占用 ' --squash'

签字人:Danny Lin

git subtree push不支持--squash,如之前在6ccc71a9中说明的(“ contrib/subtree:没有push --squash”,2015-05-07,Git v2.5.0-rc0 --批处理中列出的合并#4

文档不再提及push.

于 2015-05-25T15:56:00.517 回答