Git分支在哪里开始,它的长度是多少? [英] Where does a Git branch start and what is its length?

查看:114
本文介绍了Git分支在哪里开始,它的长度是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时候我会问,在git上启动某个分支时会发生什么,或者是否在特定的分支上创建了某个提交。分支的终点非常明确:这就是分支标签所在的位置。但是 - 它从哪里开始?微不足道的答案是:在我们创建那个分支的地方。但据我所知,这些信息就是我所知道的,这就是为什么我问这个问题,在第一次提交后就失败了。



只要我们知道我们分支的提交,我们就可以绘制图表来清楚说明:

< pre $ A - B - C - - - - J [master]
\
D - E - F - G [branch-A]
\
H - - I [branch-B]

B提交 E ,这就是开始。我知道,因为我做到了。但其他人能否以同样的方式认出它?我们可以绘制如下图:

  A  -  B  -  C  -   -   -   -  J [master] 
\
\ F - G [branch-A]
\ /
D - E
\
H - I [branch-B]

现在看图,哪个分支从 E ,哪一个在 B ?是提交 D 这两个分支的成员,还是我们可以清楚地确定它是属于分支-A还是分支-B?

这听起来有些哲学性,但实际上并非如此。主管有时想知道,分支何时开始(通常标志着任务的开始)以及某些更改属于哪个分支(为了达到某种更改的目的 - 是否需要这项工作),而且我会想知道git是否提供了信息(工具,命令)或定义来正确回答这些问题。

在Git中,你可以说每一个分支都从根提交开始,这将是完全正确的。但我想这对你不是很有帮助。你可以做的是定义分支的开始与其他分支的关系。你可以这样做的一种方式是使用

  git show-branch branch1 branch2 ... branchN 

,它将向您显示输出底部的所有指定分支之间的常见提交(如果实际上有一个常见的提交提交)。



下面是一个来自 show-branch 的Linux Kernel Git文档

  $ git show-branch master修正mhf 
* [master]添加'git show-branch'。
! [修复]将重置类型标志引入git reset
! [mhf]允许+ remote:localrefspec在读取时产生--force。
---
+ [mhf]允许+ remote:localrefspec在读取时产生--force。
+ [mhf〜1]拉多个头时使用git-octopus。
+ [修复]将重置类型标志引入git reset
+ [mhf〜2]git fetch --force。
+ [mhf〜3]使用.git / remote / origin,而不是.git / branches / origin。
+ [mhf〜4]让git pull和git fetch默认为原点
+ [mhf〜5]臭名昭着的'章鱼合并'
+ [mhf〜6]退还git -parse远程。
+ [mhf〜7]多头提取。
+ [mhf〜8]开始添加$ GIT_DIR /遥控器/支持。
* ++ [master]添加'git show-branch'。

在该例子中,正在比较 master 修复 mhf 分支。把这个输出看作一个表,每个分支由自己的列表示,每个提交获得自己的行。包含提交的分支将在该提交的行的列中显示 + - 。 / p>

在输出的最底部,您会看到所有3个分支共享一个共同的祖先提交,并且它实际上是 master : + [master]添加'git show-branch'。

这意味着修正 mhf 是从 master 中的提交内分支的。

替代解决方案



当然,这只是一种可能的方式来确定Git中的通用基础提交。其他方式包括 git merge-base 来寻找共同的祖先,并且 git log --all --decorate --graph --oneline gitk --all 来可视化分支并查看它们分歧的位置(尽管如果有很多提交很快就会变得困难)。



来自原始海报的其他问题



至于以下问题:


提交 D 是两个分支的成员还是我们可以清楚地确定它是否属于分支-A 分支-B


D 是两个分支的成员,它们是它们的祖先提交。


主管有时想知道 什么时候分支已经启动(它通常标志着任务的开始) ...


在Git中,您可以重写整个提交树的历史记录,他们的分支,所以 分支开始不像TFS或SVN那样。您可以将 rebase 分支到Git树中的任何时间点,甚至将它放在根提交之前!因此,您可以使用它在您想要的树中的任何时间点开始一项任务。



这是<$ c $的常见用例c> git rebase ,以便同步分支以及来自上游分支的最新更改,以沿着提交图形及时推送它们前进,就好像您刚刚开始在分支上工作一样,尽管你实际上已经做了一段时间。如果你愿意的话,你甚至可以按照提交图推回分支(尽管你可能需要解决很多冲突,具体取决于分支内容......或者你可能不会)。你甚至可以在开发历史中插入或删除一个分支(尽管这样做可能会改变很多提交的提交)。重写历史记录是Git的主要特性之一,它使得它非常强大和灵活。

这就是为什么提交带有创作日期(当提交最初被创作时)和提交日期(当提交最后提交到提交树时)。您可以将它们想象为创建时间日期和上次修改时间日期。


主管有时想知道...... 某些更改属于哪个分支 (以获得某些更改的目的 - 是作品需要的)。


同样,由于Git允许您重写历史记录,因此您可以(重新)基于任何所需的提交图中的任何分支/提交进行一组更改。 git rebase 字面上允许您自由移动整个分支(尽管您可能需要随时解决冲突,具体取决于您将分支移到哪里以及它包含的内容) 。

这就是说,你可以在Git中用来确定哪些分支或标签包含一组更改的工具是 - 包含

 #哪些分支包含提交X? 
git branch --all --contains X

#哪些标签包含提交X?
git tag --contains X


Every now and then I'm asked, on what commit a certain branch on git starts or if a certain commit has been created on a specific branch. The end point of a branch is pretty clear: that's where the branch label sits. But - where did it start? The trivial answer would be: on that commit where we created that branch. But that information is, as far as I know now, and that's why I'm asking the question, lost after the first commits.

As long as we know the commit where we branched off, we can draw the graph to make it clear:

A - B - C - - - - J     [master]
     \
      D - E - F - G     [branch-A]
           \
            H - - I     [branch-B]

I've created branch-B at commit E so that's the "start". I know that, because I did it. But can others recognize it the same way? We could draw the same graph like that:

A - B - C - - - - J     [master]
     \
      \       F - G     [branch-A]
       \     /
        D - E
             \
              H - I     [branch-B]

So, looking at the graph now, which branch started at E, which one at B? Is commit D a member of both branches or can we clearly decide whether it belongs to branch-A or branch-B?

This sounds somewhat philosophical but it really isn't. Supervisors sometimes like to know, when a branch has been started (it usually marks the start of a task) and to which branch some changes belong to (to get the purpose of some change - was it required for the work) and I'd like to know if git offers infos (tools, commands) or definitions to answer those questions correctly.

解决方案

In Git, you could say that every branch starts at the root commit, and that would be quite literally true. But I guess that's not very helpful for you. What you could do instead is to define "the start of a branch" in relation to other branches. One way you can do this is to use

git show-branch branch1 branch2 ... branchN

and that will show you the common commit between all specified branches at the bottom of the output (if there is, in fact, a common commit).

Here's an example from the Linux Kernel Git documentation for show-branch

$ git show-branch master fixes mhf
* [master] Add 'git show-branch'.
 ! [fixes] Introduce "reset type" flag to "git reset"
  ! [mhf] Allow "+remote:local" refspec to cause --force when fetching.
---
  + [mhf] Allow "+remote:local" refspec to cause --force when fetching.
  + [mhf~1] Use git-octopus when pulling more than one heads.
 +  [fixes] Introduce "reset type" flag to "git reset"
  + [mhf~2] "git fetch --force".
  + [mhf~3] Use .git/remote/origin, not .git/branches/origin.
  + [mhf~4] Make "git pull" and "git fetch" default to origin
  + [mhf~5] Infamous 'octopus merge'
  + [mhf~6] Retire git-parse-remote.
  + [mhf~7] Multi-head fetch.
  + [mhf~8] Start adding the $GIT_DIR/remotes/ support.
*++ [master] Add 'git show-branch'.

In that example, master is being compared with the fixes and mhf branches. Think of this output as a table, with each branch represented by its own column, and each commit getting its own row. Branches that contain a commit will have a + or - show up in their column in the row for that commit.

At the very bottom of the output, you'll see that all 3 branches share a common ancestor commit, and that it is in fact the head commit of master:

*++ [master] Add 'git show-branch'.

This means that both fixes and mhf were branched off of that commit in master.

Alternative solutions

Of course that's only 1 possible way to determine a common base commit in Git. Other ways include git merge-base to find common ancestors, and git log --all --decorate --graph --oneline or gitk --all to visualize the branches and see where they diverge (though if there are a lot of commits that becomes difficult very quickly).

Other questions from original poster

As for these questions you had:

Is commit D a member of both branches or can we clearly decide whether it belongs to branch-A or branch-B?

D is a member of both branches, it's an ancestor commit for both of them.

Supervisors sometimes like to know, when a branch has been started (it usually marks the start of a task)...

In Git, you can rewrite the history of the entire commit tree(s) and their branches, so when a branch "starts" is not as set in stone as in something like TFS or SVN. You can rebase branches onto any point in time in a Git tree, even putting it before the root commit! Therefore, you can use it to "start" a task at any point in time in the tree that you want.

This is a common use case for git rebase, to sync branches up with the latest changes from an upstream branch, to push them "forward" in time along the commit graph, as if you had "just started" working on the branch, even though you've actually been working on it for a while. You could even push branches back in time along the commit graph, if you wanted to (though you might have to resolve a lot of conflicts, depending on the branch contents...or maybe you won't). You could even insert or delete a branch from right in the middle of your development history (though doing so would probably change the commit shas of a lot of commits). Rewriting history is one of the primary features of Git that makes it so powerful and flexible.

This is why commits come with both an authored date (when the commit was originally authored), and a committed date (when the commit was last committed to the commit tree). You can think of them as analogous to create time-date and last-modified time-date.

Supervisors sometimes like to know...to which branch some changes belong to (to get the purpose of some change - was it required for the work).

Again, because Git allows you to rewrite history, you can (re)base a set of changes on pretty much any branch/commit in the commit graph that you want. git rebase literally allows you to move your entire branch around freely (though you might need to resolve conflicts as you go, depending on where you move the branch to and what it contains).

That being said, one of the tools you can use in Git to determine which branches or tags contains a set of changes is the --contains:

# Which branches contains commit X?
git branch --all --contains X

# Which tags contains commit X?
git tag --contains X

这篇关于Git分支在哪里开始,它的长度是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆