【发布时间】:2013-12-04 20:07:17
【问题描述】:
我正在使用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
如您所见,尽管我指定了 squash 选项,但 lib 看到了 "repo commit 2,3,4"。
反过来工作,因此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
【问题讨论】:
-
对于附带问题,由于
--all选项,您会看到额外的日志。使用该选项就好像您正在获取refs/中所有引用的日志,因为推送操作会在那里创建一个新引用,因此它会沿着HEAD的日志打印。 -
我认为您在附带问题中的日志是错误的,或者您创建存储库的时间可能不同,因为哈希与您上面的哈希不匹配。
-
@LopSae,谢谢 :) 有没有办法阻止推送添加新的参考?如果没有,为什么 fetch 不需要添加引用?关于附带问题,很抱歉造成混淆,我确实后来做了测试,这就是为什么提交不一样。我更新了问题。
-
通过使用
git subtree push你正在做一个split创建一个分支(额外的引用),然后推送该引用。可以单独使用split,它只会创建一个提交而不创建新分支,split只会打印创建的提交哈希。 -
我明白了,我不介意 push 创建了那个新分支,我只是不想看到它。似乎用
--branches替换--all可以解决问题,link to log manual。
标签: git push git-push git-subtree squash