Git:在不在分支中的情况下提交 master 的那个突出部分
Git: Commits that stick-out of master without being in a branch
我已经在一个项目上工作了一段时间,使用 git 本地存储库进行版本控制。
我在存储库中有两个分支:master 和 "other"(不是它的真名)。
当我 运行 git branch
我得到这个列表:
other
* master
使用 gitg 查看我的存储库图(git 的 Gnome GUI),从 分支 下拉列表中选择 "all branches"列表,我得到这张图:
我看到了两个分支,但也有两个提交,标记为 "v1.2y" 和 "v1.2s",它们从 master 分支中伸出并且似乎没有合并回它。它们似乎像非合并分支一样挂在那里,但它们不是真正的分支。至少 git 和 gitg 都没有将它们列为分支。
如果他们本身不是分支,有人可以向我解释一下他们退出 master 分支的原因吗?
请不要只是简单地告诉我如何使它正常,最重要的是,请告诉我发生这种情况的原因。
编辑:我从未进行过变基或强制推送。
首先,您可以在这里了解标签和分支之间的区别:
How is a tag different from a branch? Which should I use, here?
假设您执行以下操作:
git checkout master //go to branch master, say at commit x
git checkout -b newbranch //create a new branch called newbranch that also points to x
git commit -a -m some_branch_commit_1 //add a commit to newbranch
git tag tagged_my_commit //tag your commit
git checkout master //go back to master
git commit -a -m "Something" //add a commit, say y to master
git checkout newbranch //go back to newbranch
git rebase master //create a copy of the commits on newbranch so that they now split of from y instead of x
在这种情况下,将创建提交 some_branch_commit_1
的新副本。然而,旧的仍然存在(它被标记为tagged_my_commit
)所以它永远不会消失。
基本上,您现在有同一个提交的两个副本,其中一个不在具有特定名称的分支上。
假设您 没有 标记该提交,那么原则上它可以被 git 删除。但是,删除此类提交(垃圾收集)只是偶尔发生。这可以解释为什么不应该继续存在的提交仍然在你的 repostiroy 中。如果您想了解更多信息,请参阅 https://git-scm.com/docs/git-gc
如评论中所述,这不仅发生在 rebase 中。任何形式的重写(例如,修改提交、更改分支指针……)都可能导致您遇到这种情况。
根据要求编辑:另一个例子
git checkout master //go to master, say at commit x
git commit -a -m "I did something" //create a commit, say y1
git tag tagit //tag your commit
你的历史现在看起来像这样
y1 = master = tagit
|
x
现在执行以下操作
//编辑一些文件
git commit -a -m "I did something (more)" --amend //change commit y1 这样它现在也考虑到对其他文件的更改,说这是 y2
在那种情况下,您的历史记录如下所示
y1=tagit y2=master
| /
| /
| /
| /
| /
| /
| /
| /
x
你的情况好像是这样
我已经在一个项目上工作了一段时间,使用 git 本地存储库进行版本控制。
我在存储库中有两个分支:master 和 "other"(不是它的真名)。
当我 运行 git branch
我得到这个列表:
other
* master
使用 gitg 查看我的存储库图(git 的 Gnome GUI),从 分支 下拉列表中选择 "all branches"列表,我得到这张图:
我看到了两个分支,但也有两个提交,标记为 "v1.2y" 和 "v1.2s",它们从 master 分支中伸出并且似乎没有合并回它。它们似乎像非合并分支一样挂在那里,但它们不是真正的分支。至少 git 和 gitg 都没有将它们列为分支。
如果他们本身不是分支,有人可以向我解释一下他们退出 master 分支的原因吗?
请不要只是简单地告诉我如何使它正常,最重要的是,请告诉我发生这种情况的原因。
编辑:我从未进行过变基或强制推送。
首先,您可以在这里了解标签和分支之间的区别: How is a tag different from a branch? Which should I use, here?
假设您执行以下操作:
git checkout master //go to branch master, say at commit x
git checkout -b newbranch //create a new branch called newbranch that also points to x
git commit -a -m some_branch_commit_1 //add a commit to newbranch
git tag tagged_my_commit //tag your commit
git checkout master //go back to master
git commit -a -m "Something" //add a commit, say y to master
git checkout newbranch //go back to newbranch
git rebase master //create a copy of the commits on newbranch so that they now split of from y instead of x
在这种情况下,将创建提交 some_branch_commit_1
的新副本。然而,旧的仍然存在(它被标记为tagged_my_commit
)所以它永远不会消失。
基本上,您现在有同一个提交的两个副本,其中一个不在具有特定名称的分支上。
假设您 没有 标记该提交,那么原则上它可以被 git 删除。但是,删除此类提交(垃圾收集)只是偶尔发生。这可以解释为什么不应该继续存在的提交仍然在你的 repostiroy 中。如果您想了解更多信息,请参阅 https://git-scm.com/docs/git-gc
如评论中所述,这不仅发生在 rebase 中。任何形式的重写(例如,修改提交、更改分支指针……)都可能导致您遇到这种情况。
根据要求编辑:另一个例子
git checkout master //go to master, say at commit x
git commit -a -m "I did something" //create a commit, say y1
git tag tagit //tag your commit
你的历史现在看起来像这样
y1 = master = tagit
|
x
现在执行以下操作
//编辑一些文件
git commit -a -m "I did something (more)" --amend //change commit y1 这样它现在也考虑到对其他文件的更改,说这是 y2
在那种情况下,您的历史记录如下所示
y1=tagit y2=master
| /
| /
| /
| /
| /
| /
| /
| /
x
你的情况好像是这样