How can I easily verify my diffs are in parent branch?

6 messages, 4 authors, 2016-06-15 · open the first message on its own page

How can I easily verify my diffs are in parent branch?

From: Alex Bennee <hidden>
Date: 2016-06-15 22:43:03

Hi,

This is not the case of looking through the logs for my commit as I'm
exporting my changes from my tree into the company system through CVS.
This means all the usual commit tracking benefits are lost.

So I have a master branch which tracks this master baseline from CVS and
each release I import a big change set which includes all the fixes that
went into that baseline.

What I need to do is check that my commits that I submitted for the
baseline have been correctly merged. Of course if I do "git-diff
master..mywork" I'll see all the other code that has been added in (or
more usually is missing from my branch).

Is there an invocation of git-diff or another tool that can tell me all
my diffs are present in the big uber-commit of my master branch baseline
release?

-- 
Alex, homepage: http://www.bennee.com/~alex/
Any excuse will serve a tyrant. -- Aesop

Re: How can I easily verify my diffs are in parent branch?

From: Alex Riesen <hidden>
Date: 2016-06-15 22:43:03

On 4/4/07, Alex Bennee [off-list ref] wrote:
Is there an invocation of git-diff or another tool that can tell me all
my diffs are present in the big uber-commit of my master branch baseline
release?
You can limit git-diff to the pathnames you touched in your commits
(assuming you now the first commit you sent upstream).

git diff-tree --name-only first HEAD | while read f; do
  git diff-tree --shortstat upstream HEAD -- "$f"
done

It is very inefficient, though

Re: How can I easily verify my diffs are in parent branch?

From: Andy Parkins <hidden>
Date: 2016-06-15 22:43:03

On Wednesday 2007 April 04 12:36, Alex Bennee wrote:
What I need to do is check that my commits that I submitted for the
baseline have been correctly merged. Of course if I do "git-diff
master..mywork" I'll see all the other code that has been added in (or
more usually is missing from my branch).

Is there an invocation of git-diff or another tool that can tell me all
my diffs are present in the big uber-commit of my master branch baseline
release?
Kind of.  Try git-cherry (I like to use -v as well).  This will compare the 
hash of the diff of each of the revisions in your current branch with those 
of an upstream branch.

 * -- O -- * -- * -- C' -- * (upstream)
       \
        A -- B -- C -- D (yourbranch)

With something like the above, were C has been accepted into upstream as 
revision C', runing git-cherry on yourbranch would give:

 $ git-cherry upstream
 +A
 +B
 -C
 +D

The "-" in front of C means that you can remove C from yourbranch - it's been 
accepted.

However, this relies on the applied patch matching exactly (not the log 
message - that can be anything), so if a typo got fixed by the maintainer, it 
would show up as not having been accepted.

Another good way of telling is to rebase yourbranch onto the current 
upstream - a patch that doesn't need applying (because it's already there) 
get's dropped automatically by git.  This is really handy because git 
effectively filters those patches that you don't need to worry about any more 
in yourbranch.  This would cope with a typo fix as well, because git-rebase 
would note a conflict which you would then see as being a minor typo and 
would do "git rebase --skip" which would manually drop the patch from 
yourbranch.



Andy
-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com

Re: How can I easily verify my diffs are in parent branch?

From: Linus Torvalds <torvalds@linux-foundation.org>
Date: 2016-06-15 22:43:03


On Wed, 4 Apr 2007, Alex Bennee wrote:
This is not the case of looking through the logs for my commit as I'm
exporting my changes from my tree into the company system through CVS.
This means all the usual commit tracking benefits are lost.
Yeah, sad.
So I have a master branch which tracks this master baseline from CVS and
each release I import a big change set which includes all the fixes that
went into that baseline.
So all your small diffs get smushed in as part of one *big* change? Or do 
they still exist in the baseline CVS tree as individual commits?

If they still exist in the CVS tree as individual commits, you're slightly 
better off: you can use "git patch-id" to generate a hash of all the 
patches, and compare just the hashes. That allows you to efficiently find 
patches that have been applied *identically* in both trees.

NOTE! "git-patch-id" generates a hash of a patch by ignoring 
 - line numbers
 - whitespace
 - commit comments
so "identical" means just that the patch has to have the exact same 
context and +/- patterns, but it will still be considered identical if 
it's been moved around (perhaps because some other patch added/removed 
code before it) or if the whitespace has been tweaked.

You can then compare the hashes upstream with all the commits *you* cared 
about, and see if they are all there. But as noted, this only works if 
upstream is expected to actually honor patch-boundaries. If you just get a 
single big changeset that contains *all* the changes, doign this obviously 
won't work.

NOTE2! I don't think anybody actually *uses* git-patch-id, and what you 
should do is to use "git cherry" that does this all internally, but it is 
worth understanding *what* git-cherry does.

So to compare all patch-ID's, you can do

	git cherry cvs-upstream my-branch

adn it should look at all the commits that are in *your* branch but not 
upstream, and report their ID's preceded by a "-" if they are upstream, 
and a "+" if they are not.

You can then look at the "+" commits more closely, to see whether maybe 
they actually did get merged, but got changed/fixed in the process, or 
whether they really are missing.
Is there an invocation of git-diff or another tool that can tell me all
my diffs are present in the big uber-commit of my master branch baseline
release?
If git cherry doesn't work for you, you're kind of screwed and have to do 
it manually. Of course, even "manually" can be done with a lot of help 
from git.

For example, one thing you can do, if the number of commits you have is 
fairly small, is to just be on your "my-branch" and then do

	git rebase [--merge] cvs-upstream

which will rebase your "my-branch" onto the CVS upstream thing. It will 
automatically discard any patches that get merged away (which effectively 
means that they were already there). The end result will be that your 
branch will now either be identical to "cvs-upstream" (if everything was 
already there) or will contain the commits that weren't there on top of 
the new cvs-upstream tip.

NOTE NOTE NOTE! The "git rebase" thing sounds perfect, but the fact is, 
quite often you'll end up having to help it do its work. It really 
defaults to just trying to apply the patches (ie without "--merge" it's 
literally just a fancy

	git-format-patch | git am

pipeline).

So "git rebase" may well be the right thing for you, but quite frankly, 
it's more likely to work well for simple cases (with no real conflicts 
with anybody elses work in the same areas) than for anything complicated.

For complicated stuff, you'll be on your own. "git diff pathname" etc..

		Linus

Re: How can I easily verify my diffs are in parent branch?

From: Alex Bennee <hidden>
Date: 2016-06-15 22:43:03

On Wed, 2007-04-04 at 08:12 -0700, Linus Torvalds wrote:
On Wed, 4 Apr 2007, Alex Bennee wrote:
quoted
This is not the case of looking through the logs for my commit as I'm
exporting my changes from my tree into the company system through CVS.
This means all the usual commit tracking benefits are lost.
Yeah, sad.
<snip>
So all your small diffs get smushed in as part of one *big* change? Or do 
they still exist in the baseline CVS tree as individual commits?
Unfortunately they are all smushed together :-(

<snip>
For example, one thing you can do, if the number of commits you have is 
fairly small, is to just be on your "my-branch" and then do

	git rebase [--merge] cvs-upstream
Yeah I've tried using the rebase approach (which I in fact use a lot
when re-baseing my work anyway without losing my micro commit history).
The one fly in the ointment is the branch result at the end contains no
changes so I have no historical record of what I did while creating the
change.

I assume the commit objects are still in git somewhere but I'm not sure
how to get at it. What I would like to ask git is "what did my git-log
look like when 'mybranch' was based off master at A instead of B after O
rebased?"

For the time being I tend to verify my work has got in by generating a
master..branch diff and loading it into emacs patch-mode and testing
each hunk has applied ok. I'm still deciding if I should bite the bullet
and write some more elisp to make it a one button operation or use a bit
of perl with git. 


-- 
Alex, homepage: http://www.bennee.com/~alex/
"The most difficult thing in the world is to know how to do a thing and
to watch someone else do it wrong without comment." -- Theodore H. White

Re: How can I easily verify my diffs are in parent branch?

From: Linus Torvalds <torvalds@linux-foundation.org>
Date: 2016-06-15 22:43:04


On Wed, 11 Apr 2007, Alex Bennee wrote:
On Wed, 2007-04-04 at 08:12 -0700, Linus Torvalds wrote:
quoted
Yeah, sad.
<snip>
So all your small diffs get smushed in as part of one *big* change? Or do 
they still exist in the baseline CVS tree as individual commits?
Unfortunately they are all smushed together :-(
Ok, that just sucks.
quoted
For example, one thing you can do, if the number of commits you have is 
fairly small, is to just be on your "my-branch" and then do

	git rebase [--merge] cvs-upstream
Yeah I've tried using the rebase approach (which I in fact use a lot
when re-baseing my work anyway without losing my micro commit history).
The one fly in the ointment is the branch result at the end contains no
changes so I have no historical record of what I did while creating the
change.
Ok, that's what "rebase" is *meant* to do. If the upstream already 
contains the patch (which especially with "--merge" means that it just 
cleanly did a 3-way merge - whether upstream was one big smushed- 
together thing or actually contained that patch explicitly doesn't 
matter), then "rebase" just skips that patch, since it's not "necessary" 
any more.

If you actually want to keep your own cleaner history, you should really 
do a "git merge", not a rebase. That's kind of the fundamental difference 
between rebasing and merging: rebasing throws away the old history (and 
creates totally new commits to keep the stuff that wasn't there), while 
"merge" creates a *superset* of the two histories.
I assume the commit objects are still in git somewhere but I'm not sure
how to get at it. What I would like to ask git is "what did my git-log
look like when 'mybranch' was based off master at A instead of B after O
rebased?"
What you *can* do, is to do "rebase *and* merge" kind of operation, if 
you really want to.

Your history will look a bit odd, and you'll have unmerged commits always 
show up twice (or as many times as you do this operation, in fact - if you 
keep on doing it, and they don't get merged up-stream, they'll always be 
re-done over and over again). But you'll have *both* the rebase result 
*and* the merge result.

The way to do that would be to basically be something like this by having 
*three* branches rather than two: your CVS import branch (call it "cvs"), 
your "merged work" branch (call it "cvs-merged") and the branch you 
actually do development on (call it "master")

 - update the "CVS tracking branch"

	# something like this.. 
	git cvsimport -i -m -o cvs

 - switch to the "cvs-merged" branch, and merge your old changes *and* the 
   new CVS state into it, but merge it as the CVS state *only*:

	# reset the "cvs-merge" branch to the new "cvs" state
	git branch -f cvs-merge cvs

	# switch to it
	git checkout cvs

	# and merge your old "master" into it but only merge the history, 
	# not the actual contents (ie using the "ours" strategy)
	git merge -s ours master

 - now, go back to your development branch, and rebase the work you have 
   there into the cvs-merge branch that works as the "history branch"

	# switch back to the development branch (which doesn't have the merge)
	git checkout master

	# Now, rebase the stuff that was *not* int he original "cvs" 
	# branch, but is in your development branch, and put it on top of 
	# the merge you just did.
	git rebase --merge --onto cvs-merge cvs

which *should* mean that in the end you have your "master" branch that 
contains your old history *and* the CVS history merged, *and* on top of 
that merge it also has the patches that you had in your old history that 
weren't in the CVS tree.

(The above is just a rough idea - I'm not actually guaranteeing that it 
works, I didn't test it, I just wrote it up as an example. That last 
"rebase" in particular might need some work to make sure that it only 
rebases your new stuff since the last cvs-merge: I think it will do that 
as-is, but I've always found the "git rebase" command to have very 
non-intuitive semantics because it doesn't use the normal "range" 
operations to describe what to actually rebase).

You get the idea. Once you get that working, you can just script it. The 
whole point is that you can use a merge *and* a rebase to both save away 
your old history, *and* to then re-do the commits that weren't merged on 
top of it.

So you *can* keep both the history *and* rewrite it, but it will require 
you to do more work, and you'd have to experiment a bit (as mentioned, I 
really don't think that "git rebase" example I gave above necessaly works 
as-is - you might have to tweak it a bit to make sure that it rebases 
exactly the commits that have been done since the last cvs merge: it might 
involve using "git-merge-base" to figure out what the last merge was 
before you do the "git merge -s ours" thing etc etc)

		Linus
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help