Re: [git-users] Commits finding their way from one branch to another?

2014-04-09 Thread Konstantin Khomoutov
On Wed, 9 Apr 2014 08:34:53 -0700 (PDT)
Fabio Sobral flsob...@gmail.com 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
result.  What happens is that there will be a merge commit, changes
from B will be in the resulting state but there will be no C's changes!
I'm also able to *introduce* arbitrary changes, not present in neither A
nor B, before recording a merge commit.
The same logic applies to cherry picks: no one prevents you from
changing the changes it brings in arbitrary ways before recording a
commit.

What I'm leading you to is that while considering merge commits as the
points of bringing in changes is okay and useful but it implies
everyone doing merge commits plays by the rules, and it's textual
changes what matters, not how the history looks like in a history
browser.  You might also find reading the second part of [1]
particularly amusing.

So start with `git blame`.  If that does not work try resorting to
`git fsck` (a thread a day ago dealt with it so you might look it up)
but really I don't beleive in repository breakage.

1. http://randyfay.com/content/avoiding-git-disasters-gory-story

-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [git-users] Commits finding their way from one branch to another?

2014-04-09 Thread Fabio Sobral
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