1

How's everyone doing? Have run into an issue with GIT where I can't determine which child node is on the same branch as the parent and which one is a new branch: git tree example for below commits

As can be seen, there are tags but no branch names in the local/remote project.

tag "3.2ECHO1.1" -> parent: d42624
first green commit -> child 1: c1749e
first pink commit -> child 2: 404c71

If I run any of the following commands:

git branch -a --contains c1749e
git branch -a --contains 404c71
git branch -a --contains d42624

the result is an empty line for each.

Question: given a git parent commit, how does one determine which child is on the same branch and which child was a new branch? I would like to recreate the exact structure of this project into a new project.

Thanks

  • 1
    [This](https://stackoverflow.com/questions/58416014/how-can-i-find-the-first-commit-of-a-branch-with-jgit/58595799#58595799) answer to someone with the same preconceived notion of what "branches" are might prove helpful. Older vcs's want a unique mapping from commits to branches. That notion leads to trouble, and Git ditched it. – jthill Oct 01 '21 at 22:43
  • @jthill To be fair, it's not just *older* VCSes: as I understand it, Mercurial also has a concept of "branch" which is recorded on every commit, but different again from what it means in, say, Subversion. Your key point is very true, though: git does not. – IMSoP Oct 02 '21 at 10:20
  • @IMSoP Mercurial kept that heavyweight abstraction (among others) larded on top of the history structure, yes. But older vcs's were pretty much forced to promote deltas to first-class internal objects by the hardware constraints of the time, which meant a lot of the costs of cementing content and structure together like that seemed intrinsic or inevitable or something. Try telling anyone writing anything for publication in any other field that an editing pass is blasphemous and they'll just laugh at you. But a few rounds of editing pass on history being prepared for publication is what, now? – jthill Oct 02 '21 at 18:32
  • @jthill Frankly, I don't know enough about a) Mercurial, or b) whatever analogy you're making there, to comment on if the analogy is sound. What I *do* know is that there are many VCSes with different design decisions, and git has succeeded partly through "network effects" (i.e. fashion), and only partly through actual superiority to other tools. I think it's foolish to look at every decision git's authors made, and call any tool that didn't make the same decision "old-fashioned", rather than being curious how different people have tackled the same problems. – IMSoP Oct 02 '21 at 22:49

2 Answers2

3

No child is ever contained by a parent. Children contain, i.e., are descended from, parents, and never vice versa. The arrows point backwards, not forwards.

torek
  • 448,244
  • 59
  • 642
  • 775
0

In git, branches don't really exist. A branch is actually recorded the same way as a tag, just moved more often: it points at a single commit, so that you can refer to that commit more conveniently than by its unique hash. From that single commit, you can reach every ancestor of that commit, back to the root of the repository, by following "parent" pointers.

I would like to recreate the exact structure of this project into a new project.

The structure of the project is the graph that you showed; it is recorded as a series of immutable commits, each of which has zero or more references to "parents" - 1 for a "normal" commit, 2 for a typical "merge commit". The parents are stored as an ordered list, and by convention the first parent is the commit which was checked out when a merge happened; so graph views will try to keep a line of first parents more straight.

There is no record of where branch pointers were created, moved, or deleted, so if the branches don't exist right now, you can't recreate them - and even if they do exist right now, you can't necessarily tell exactly what their history is.

given a git parent commit, how does one determine which child is on the same branch and which child was a new branch?

You have to flip this around: given the current location of some branch pointer, you can determine if a particular parent commit is in the current history of that branch. But go deep enough into the repository, and your commit will be an ancestor of every current branch; there is no way to choose which is the "must relevant" descendant.

IMSoP
  • 89,526
  • 13
  • 117
  • 169