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

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

问题描述

时不时有人问我,git 上某个分支的提交是什么,或者某个提交是否已在特定分支上创建.分支的终点非常清楚:那是分支标签所在的位置.但是——它从哪里开始?简单的答案是:在我们创建那个分支的那个提交上.但是,据我现在所知,这些信息在第一次提交后丢失了,这就是我问这个问题的原因.

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]

我在提交 E 时创建了分支 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]

那么,现在看图表,哪个分支从 E 开始,哪个分支从 B 开始?commit D 是两个分支的成员还是我们可以明确决定它属于分支A还是分支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?

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

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.

推荐答案

在 Git 中,您可以说每个分支都从根提交开始,这确实是真的.但我想这对你不是很有帮助.您可以做的是定义与其他分支相关的分支的开始".一种方法是使用

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).

这是 Linux 内核 Git 文档中 的示例显示分支

$ 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'.

在该示例中,将 masterfixesmhf 分支进行比较.将此输出视为一个表,每个分支由其自己的列表示,每个提交都有自己的行.包含提交的分支将在该提交的行中的列中显示 +-.

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.

在输出的最底部,您会看到所有 3 个分支共享一个共同的祖先提交,并且它实际上是 masterhead 提交:

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'.

这意味着 fixesmhf 都是从 master 中的那个提交分支出来的.

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

替代解决方案

当然,这只是确定 Git 中公共基础提交的一种可能方法.其他方法包括 git merge-base 查找共同祖先,以及 git log --all --decorate --graph --onelinegitk --all 来可视化分支并查看它们的分歧点(尽管如果有很多提交会很快变得困难).

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).

来自原始海报的其他问题

至于您提出的这些问题:

As for these questions you had:

commit D 是两个分支的成员还是我们可以明确决定它是属于branch-A 还是branch-B?

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

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

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)...

在 Git 中,您可以重写整个提交树及其分支的历史记录,因此 分支开始"并不是一成不变的就像在 TFS 或 SVN 之类的东西中一样.您可以rebase 分支到 Git 树中的任何时间点,甚至可以将其放在根提交之前!因此,您可以使用它在树中的任何时间点启动"任务.

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.

这是 git rebase 的一个常见用例,将分支与来自上游分支的最新更改同步,沿着提交图及时将它们向前"推送,就好像你有刚刚开始"在分支上工作,即使您实际上已经在它上面工作了一段时间.如果您愿意,您甚至可以沿着提交图及时将分支推回(尽管您可能必须解决很多冲突,具体取决于分支内容……或者您可能不会).您甚至可以在开发历史的中间插入或删除一个分支(尽管这样做可能会更改许多提交的提交 shas).重写历史记录是 Git 的主要功能之一,它使它如此强大和灵活.

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).

同样,因为 Git 允许您重写历史记录,所以您可以(重新)根据您想要的提交图中的几乎任何分支/提交来(重新)基于一组更改.git rebase 实际上允许您自由移动整个分支(尽管您可能需要随时解决冲突,具体取决于您将分支移动到的位置以及它包含的内容).

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).

话虽如此,您可以在 Git 中用来确定哪些分支或标签包含一组更改的工具之一是 --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天全站免登陆