0

I found a very weird issue today. We have two teams working on the same repo, but different branch.

Let's say, team-A working on branch AA; and team-B working on branch BB.

The spooky things just happened without any sign, i found lots of commits were brought from BB to AA by a team-A member along with his one specific commit as below.

enter image description here

This is the commit from team-A member, but the Parent field points to a commit which belongs to BB(which is impossibble in my opinion). That might be the reason this commit brought lots of commits from another branch.

I just talked to team-A member, he never checkout BB(i saw his repo, there is no local branch BB), Does anyone know how could it happen? and why?

Is it possible a bug of Git or WebStorm? Team-A member is using git 1.9.1 and WebStorm Build #WS-162.1121.31, built on July 9, 2016.

Edited:

So far, while executing git reflog, i found one questionably command executed 13579cd8d HEAD@{202}: reset: moving to 13579cd8. I am pretty sure this team-A member won't do that(he never know there is a branch BB, not to know the commit 13579cd8 on it). And he's using WebStorm as working tool, so might be bug of WS, or he has some misoperation

Howard
  • 4,474
  • 6
  • 29
  • 42
  • Look at this [answer](http://stackoverflow.com/questions/3042437/change-commit-author-at-one-specific-commit). – Maroun Dec 28 '16 at 09:20
  • The `team-A` member didn't even know there is a branch *BB*. And i am sure he would never do `rebase -i`. Is there any other may? Thanks – Howard Dec 28 '16 at 09:37

2 Answers2

1
  • One reason can be commits of BB are merged with remote/master and then any member of team-A pull remote/master into AA.

  • Or, If team-A member pull branch BB directly into AA (git pull origin BB) then, BB's commits will be available in AA.

Sajib Khan
  • 22,878
  • 9
  • 63
  • 73
  • The team-A member is quite junior, he does even know there is a branch *BB*, so i don't think he would typing `git pull origin BB`. But for the first reason you mentioned, is there any way that command can be done by IDE(he is using WebStorm). Thanks – Howard Dec 28 '16 at 09:35
  • * First, make sure the `BB's` commits are available in `master`. `git checkout master && git pull origin master`. Then check if the commits are available here. * "that command can be done by IDE" - yes the command can be easily by `VCS | git | git branches | origin/master | merge` in WebStorm. – Sajib Khan Dec 28 '16 at 09:42
  • I checked just now, *BB*'s commits only available on *BB*. Thanks for your quick answer, i will dig further more – Howard Dec 28 '16 at 09:54
1

You have snipped so much that it is not possible to tell whether the commit in question is a merge commit. I suspect it is: that someone ran git merge, perhaps by running git pull (git pull runs git fetch and after the fetch is done, runs either git merge or git rebase, defaulting to the wrong one—I advise new users to avoid git pull as its convenience turns out to be more of a trap than a help).

Background

The default (single) parent of a new commit is the current commit. Branch names are not relevant to this part of the process; what matters is the current commit.

When you make a new ordinary commit with git commit, this is what normally happens, in this order:

  1. Git checks that the index (also called the staging area) has different content from the HEAD commit. (This is to prevent you from accidentally making trivial commits with no difference from the previous commit.)
  2. Git collects a commit message.
  3. Git turns the index into a snapshot.
  4. Git writes a new commit with:
    • the message you provided as the log message,
    • the user making the commit as both author and committer,
    • the current time and date as the time-stamp, and
    • the current commit ID (from git rev-parse HEAD) as the parent commit ID.
  5. Finally, Git takes the new commit ID generated in step 4 and writes that to the current branch name.

Note that except for step 5—the part that updates the current branch, so that the new commit as now at the branch's tip—the current branch's name does not enter into the picture here. (Of course the last step is important, in the end.)

There are various ways to modify the above steps, e.g., git commit --amend sets the new commit's parent(s) the same as the current commit's parent(s), and doing a regular merge that is either conflicted, or stopped-before-committing (via --no-commit), leaves behind traces that make the next commit record multiple parents. And of course a regular (successful) merge writes a commit with at least two parents, i.e., a merge commit.

Besides the above, two of the bullet-point items—author and committer, and the corresponding time-stamps—can be set to anything the person making the commit likes, either through configuration items (user.name and user.email) or through environment variables (GIT_COMMITTER_NAME, GIT_AUTHOR_DATE, and so on). The git commit command even has flags --author= and --date= to override them.

So, there are multiple ways for these things to happen, and branch names are the wrong place to focus. What matters is not so much the names, as the commit IDs. Of course, the new commit—whether it is an ordinary commit from git commit, or a merge commit from git merge—does go on the current branch, so here the name does matter.

Merge commits

I mentioned merge commits several times above. A merge commit is simply a commit with two or more parents. More than two is unusual—it's called an octopus merge, and mostly they are made by mistake when people run git pull, because git pull doesn't do what people expect it to do.

The first parent of any merge commit is handled the same way as the only parent of any ordinary, non-merge commit: it's the commit that was current when you made the merge. The second parent, and any additional parents, are all the other commits you passed as arguments to git merge.

Note that if you mistakenly do:

git pull origin branch1 branch2

Git translates this into, in effect:1

git fetch origin &&
  git merge origin/branch1 origin/branch2   # DANGER

This second command, merging two branches into the current branch, is what makes an octopus merge. Chances are you did not want that.

(Recovering from this is ... annoying and difficult, once it's pushed back. Until then, it's not too bad: as long as you keep the mistake in your own Git repository, you can back it out without consequences to anyone else, using git reset.)


1There are some minor technical differences in the git merge step, since it's actually done by commit IDs recorded in FETCH_HEAD and with an explicit merge commit message that uses, e.g., "branch 'branch1' of remote 'origin'" as its string, rather than "remote-tracking branch 'origin/branch1'" as its string. But the idea is the same.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Sorry for my unclear question. The thing is, i really have no idea what happened to team-A member's laptop. I can only describe what i saw. So far, while executing `git reflog`, i found one questionably command executed `13579cd8d HEAD@{202}: reset: moving to 13579cd8dc6cc5e48ba604371d0376704f8644cc`. I am pretty sure this member won't do that(junior developer). And he using WebStorm as working tool, so might be bug of WS, or he has some misoperation. Thanks for your detailed explaination – Howard Dec 29 '16 at 02:08
  • I know nothing of WebStorm, so it could be a bug there, I wouldn't know. :-) – torek Dec 29 '16 at 02:19