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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Wed, 11 Apr 2007, Alex Bennee wrote:

> On Wed, 2007-04-04 at 08:12 -0700, Linus Torvalds wrote:
> > 
> > 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.

> > 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
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]