我正在使用git 1.7.1访问bitbucket.org存储库的结帐。
我有两个标签:TAG1
和TAG2
。我跑:
git branch --contains `git rev-list -1 TAG1`
git branch --contains `git rev-list -1 TAG1`
git branch --contains `git rev-list -1 TAG2`
请注意,在每种情况下git rev-list
都会返回有效的哈希值。这部分命令没有问题。我不妨问一下
两个不同的提交。
第一个命令有输出:
* (no branch)
第二个命令根本没有输出。我的第一个问题是什么
输出* (no branch)
和无输出之间的差异是什么?
我的第二个问题是,如何创建一个不响应上述命令而没有输出的标签?
答案 0 :(得分:0)
首先,简要说明:没有必要git rev-list -1 <name>
。您通常可以直接使用<name>
,如果没有,git rev-parse <name>
会在不执行提交图形行走的情况下获取哈希ID(即git rev-list -1 <name>
或git rev-list --no-walk <name>
生成< em>与<{1}}相同的哈希ID。
git rev-parse <name>
:没有输出vs&#34;没有分支&#34; 根本没有输出意味着没有找到符合您条件的分支。但是,要解释git branch --contains
,请查看* (no branch)
的输出,并考虑&#34;分离的HEAD&#34;情况下:
git branch
已加星标的分支是我目前的分支。如果我现在通过哈希ID或类似的&#34; specific-commit-finder&#34;来检查特定的提交,以便进入&#34;分离的HEAD&#34;模式,然后再次运行$ git branch
diff-merge-base
* master
precious
stash-exp
:
git branch
您可以看到我现在位于没有名称的分支上:它是提示提交为$ git checkout master~5
Note: checking out 'master~5'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
HEAD is now at 1f73ff0... Merge branch 'jk/reset-to-break-a-commit-doc-updated'
$ git branch
* (HEAD detached at 1f73ff0)
diff-merge-base
master
precious
stash-exp
的分支。如果我寻找包含提交1f73ff0
或其祖先之一的分支,我应该找到我当前未命名的分支......我会这样做:
1f73ff0
我的Git说$ git branch --contains HEAD
* (HEAD detached at 1f73ff0)
master
的原因是我的比你的更新;旧版本只是说(Head detached at ...)
。在任何情况下,当您处于分离的HEAD模式时,这只能 ,并且您所在的无名分支是(no branch)
指向的分支。当您在Git历史记录中的各种提交中移动HEAD
时,此无名分支将从提交更改为提交。
您可以像Git上面提到的那样,随时创建一个 new 分支名称,指向任何现有的提交。要指向当前(HEAD
)提交 - 无论您的HEAD是否已分离 - 您都可以使用HEAD
。要通过其哈希ID或git checkout -b <new-branch-name>
等相对名称指向(并同时检出)某些其他提交,您将使用master~30
。您也可以使用git checkout -b <new-branch-name> <hash-ID-or-relative-name>
命令创建新的分支名称,而无需检查任何内容,也不能以任何方式移动HEAD:例如git branch
- 您可以删除 a任何时候的分支名称,例如,git branch thirtyback master~30
(git branch -D thirtyback
是&#34;强制删除&#34;,即删除它是否&#34;安全&#34; ;;使用-D
进行安全带检查。
(要将我的HEAD重新附加到-d
我现在运行master
。)
很容易,真的。 :-)提交是&#34; on&#34;任何分支,通过从该分支指向的提交开始,Git可以通过通常的提交图形步骤查找提交。
考虑这张图:
git checkout master
其中每个单个字母代表一个提交哈希。名称... <- E <- F <- G <-- branch
指向(包含ID)提交branch
。提交G
指向(包含ID)提交G
,F
指向F
,依此类推。
这意味着,如果您选择带有历史记录(如E
那样),则名称git rev-list
会引用以branch
开头并向后工作的每个提交。
现在让我们在绘图中添加另一个分支(由于没有向上或向下指向和的文本箭头,我将停止绘制内部箭头):
G
现在提交 F--G <-- branch
/
...--E
\
H--I <-- anotherbranch
和F
与以前一样G
,branch
和H
在I
上。但是提交anotherbranch
在两个分支上。
现在让我们看看同一个图表,但删除了分支名称E
的位置:
anotherbranch
提交 F--G <-- branch
/
...--E
\
H--I [abandoned]
和H
保留在存储库中直到收集垃圾,因此我们可以在其哈希ID上使用I
。在它们消失之前 - 甚至在我们删除分支名称之前 - 让我们添加一个指向提交git branch --contains
的标记名称:
H
标记名 F--G <-- branch
/
...--E
\
H--I [abandoned]
^
|
tag:foo
现在可以保证提交foo
永久保留在存储库中(或直到标记H
被删除)。提交foo
仍然没有名称,并且最终仍然被垃圾收集,给出:
I
如果我们询问哪些分支包含提交 F--G <-- branch
/
...--E
\
H
^
|
tag:foo
,则答案为无 - 当然,除非我们H
,它为我们提供了一个带有git checkout foo
命名提交{{1}的分离HEAD在这种情况下答案是HEAD
或H
。