Thanks for your reply, and please don't worry about nitpicking, I agree
it's important to use a terminology we can all understand, but
unfortunately as you can see I lack the knowledge to do so. Even if my
problem isn't solved, at least I get to learn more about Git. :)
I understood your reasoning, but when I said a commit appeared where it
shouldn't be I was really talking about the commit itself, and not the
textual changes.
For instance, that commit I used on my example was actually made about 18
months ago on the so called developMajor branch. That's what we remember to
have done, and in fact there were a few minor releases done meanwhile that
do not contain this change.
Iff you look at our authorative repository history it will say this
particular commit, made 18 months ago and identified by a unique sha1-id
was applied to many of our branches.
However, if you check my co-workers local repository its history says this
same commit with the same unique sha1-id was applied only to the
developMajor branch.
Cherry-pick and editing by hand wouldn't have that affect, these would be
part of a new commit, right?
We use the merge workflow, and correct if I'm wrong, but that means that it
shouldn't be possible to apply a commit from one branch to another without
creating a new commit in the process.
I agree that this was most likely caused by user error, but AFAIK this
would require something like a force push.
On Wednesday, April 9, 2014 1:18:35 PM UTC-3, Konstantin Khomoutov wrote:
On Wed, 9 Apr 2014 08:34:53 -0700 (PDT)
Fabio Sobral flso...@gmail.com javascript: wrote:
[...]
Let's say we have a Java class with a field declared as Object, but
for some reason we decided it should actually be an int[], so we
changed it on the developMajor branch only.
[...]
After checking every commit that changed the file I finally got to
that commit we made six months ago only to developMajor, and now it
says it was applied to both developMajor and develop! There's no way
this could go unnoticed for 6 months!
I checked with my co-workers and one of them that hasn't been working
on this particular project last updated his repo about 3 months ago.
So I checked out his version of the develop branch and the damned
field is declared as Object, as it should be. The history also says
that commit made 6 months ago was applied only to the developMajor
branch.
I don't know how this happened, but apparenly this commit leaked from
one branch to the other in the past 3 months. Should that even be
possible?
You should possibly excercise a bit more caution with terminology:
commits in Git never leak anywhere in any form: once created, a
commit is persisted in the repository and never changes. Moreover, Git
branches do not own commits, and commits do not belong to branches:
a branch or a tag is merely a pointer to a single commit, and it's that
commit's link to its parent (then and further down) that forms what we
preceive as a branch.
(I'm nitpicking because to comprehend possible causes for your trouble
it helps to have a clear picture of how Git represents the
history of a project it maintains.)
What might legitimately leak between branches are *textual changes.*
Let me repeat: only textual changes only ever move between commits
(and hence branches), when needed.
There are three legitimate causes for a textual change made in a commit
to appear in another:
1) True merge (that is, not fast-forward, which is a trivial case).
2) Cherry pick.
3) Editing a file by hand.
While I beleive (as opposed to thinking) it might be technically
possible for such a textual change to surprisingly appear in an
unexpected line of development due to some repository corruption,
I'd first check wastly more possible reasons such as user error.
To do this, use the `git blame` tool which is able to tell you who and
when introduced a particular change to a file.
Let me reiterate on the importance of understanding the distinction
between commits and textual changes with regard to the contents of the
files. Consider a simple true merge. Suppose we have two lines of
history, with tip commits A and B, respectively; B has some commit
C in its line of history which introduced a change which is present
in B, and we're about to merge B into A. Normally after doing this
the resulting commit will refer to a state of the repository which has
both changes contained in A and B. So the resulting merge commit M is
usually said to contain the changes of A and B, both. That's what
everyone knows about merge commits and that's how merge commits are
used to both bring other changes in and form a history graph.
But obviously no one prevents me from running the merge using the
--no-commit command-line option, then update the staging area so that
it excludes the changes introduced by commit C and then commit the