0

My employer's integration team has a very complex model that they don't clearly describe. They also change their policies at different points in the release cycle.

I'm trying to figure out whether a given set of pull requests were ultimately merged to various release line branches.

What I think I want is (1) a list of all changes that affected the code I'd see if I did "git checkout master". (2) Another list of all changes that I'd see on rel/foo. (3) Ditto for rel/bar.

I would expect "git log" to be able to produce such a list, but I see nothing obviously relevant in its man page.

Even better would be some smart tool which I could feed a list of pull requests and find out which branches contained those changes.

AFAICT, the integration team here changes the bug number and comments when merging. (The comments remain human-recognizable, but 'diff' might be confused.) They also quite reasonably combine all the commits in a given pull request into a single merge to each target branch.

Any suggestions for how to figure out what they've done, or more importantly NOT done?

If I have to, I'll resort to diffing the source code from the release branches, and doing "git blame" for anything that's in one only place, to determine what release lines it ought to be in, but there really ought to be a more straightforward way to do this kind of audit. (And also, that method won't show unintended merges.)

Has anyone got a canned command for this? Or an explanation of git's branching model that would make sense to someone used to more traditional source control tools?

Arlie Stephens
  • 1,146
  • 6
  • 20
  • I don't think you want what I think you think you want. I think. :-) One of the big stumbling blocks for those moving from previous version control system $vcs to Git is that in Git, the branch that a commits are "on" is not a useful metric, because branch *names* are virtually irrelevant: a commit is on *every* branch from which it is reachable, and moving the names around, or adding or deleting names, changes the *set of names* for any given commit, without changing the commit itself at all! This is a big surprise coming from $vcs (for nearly all other vcs-es). – torek Aug 01 '17 at 20:34
  • That just seems like semantics. I'm not concerned about where it was first committed or anything like that. Just which branches inherited it, had it merged to them, or whatever. Put another way, I want to know whether my changes made it into all appropriate release lines. – Arlie Stephens Aug 01 '17 at 20:47
  • I wish I could post live output from "git log" to explain my confusion, but that wouldn't be acceptable to my employer. – Arlie Stephens Aug 01 '17 at 20:49
  • Well ... https://english.stackexchange.com/questions/97318/is-the-phrase-its-just-a-matter-of-semantics-meaningless Anyway, more important, I think, is this part: *They also quite reasonably combine all the commits in a given pull request into a single merge to each target branch*. A critical item here is whether this is a *merge commit*, or whether this is done with Git's so-called *squash merge*, which is not a merge at all. – torek Aug 01 '17 at 20:51
  • Looks like my question may be a duplicate of https://stackoverflow.com/questions/1419623/how-to-list-branches-that-contain-a-given-commit?rq=1 – Arlie Stephens Aug 01 '17 at 20:52
  • You might also want to look at `git log --graph`, perhaps with the help of "a dog": `git log --all --decorate --oneline --graph`. (Some GUI viewers, and gitk, try to draw a good graph too, though in real repositories it rapidly gets way out of hand.) – torek Aug 01 '17 at 20:53
  • I do not understand. `git log foo` (with no other optons) just shows all commits which are in branch `foo`. What in that output is wrong for you? – max630 Aug 01 '17 at 20:54
  • @ArlieStephens: if `git branch --contains` is the right answer, then the question was reversed: you don't want to know which commits *C1, C2, ..., Cn* are reachable from branch *B*, but rather, given some commit *C*, which names *B1, B2, ..., Bn* reach commit *C*. – torek Aug 01 '17 at 20:57
  • @torek I have a list of commits and a list of branches. The commit list is longer, so I'd rather do the check in reverse. But it can be done either way. – Arlie Stephens Aug 03 '17 at 19:22
  • @max630 Adding a filename doesn't help. I still see multiple log entries with the same checkin comments. I suspect them of being merges; branch A--> branch B--> master, or worse - with all 3 of them showing in master. No idea how our build and integration team manages to do that. – Arlie Stephens Aug 03 '17 at 19:24
  • 1
    The reverse test, given a branch name *B*, is whether some commit *C* is an ancestor of the tip of *B*. That test is implemented (shell-call-able, that is) by `git merge-base --is-ancestor`, which exits with a true status (zero) if some commit argument *C* is an ancestor of some second commit ID (in this case the branch tip's commit hash, which you get by passing *B* as the second argument). – torek Aug 03 '17 at 19:31
  • @torek Would you mind creating an answer from your comment that can be accepted? – AnimiVulpis Aug 05 '17 at 10:05
  • @AnimiVulpis I'm still not even sure what the real *question* is. In particular, if pull requests get merged via "squash merge" (which is not an actual merge) there is no good answer at all. – torek Aug 05 '17 at 16:26
  • Joy. Sometimes git is too smart for anyone's good. I want to know whether a set of commits from a collection of branches got merged to a collection of release lines. And if not, which commits got omitted. I finally resorted to examining the source code in the various release lines :-( – Arlie Stephens Aug 07 '17 at 00:43

0 Answers0