git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Following history of a copied file from another indirect branch
@ 2010-10-21 18:47 Joshua Jensen
  2010-10-21 19:39 ` Brian Gernhardt
  2010-10-22  6:35 ` Johannes Sixt
  0 siblings, 2 replies; 4+ messages in thread
From: Joshua Jensen @ 2010-10-21 18:47 UTC (permalink / raw)
  To: git@vger.kernel.org

It has become a necessity to copy a file from one long-lived branch to 
another.  It is not possible to merge the branches at this time.

I would like to have 'git gui blame' follow the copy back through its 
original history, but I don't believe Git has metadata for storing 
this.  Something along the lines of a 'followparent' in the commit 
object, for instance, would allow the revision walking code to wander 
the history down an alternate line.

By comparison, integrates work at a file level in Perforce.  That means 
I can integrate a file from one branch to another, and parentage is 
stored such that I can follow the file back through its history.

Are there any facilities to do this now?

Thanks!

Josh

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Following history of a copied file from another indirect branch
  2010-10-21 18:47 Following history of a copied file from another indirect branch Joshua Jensen
@ 2010-10-21 19:39 ` Brian Gernhardt
  2010-10-21 20:06   ` Joshua Jensen
  2010-10-22  6:35 ` Johannes Sixt
  1 sibling, 1 reply; 4+ messages in thread
From: Brian Gernhardt @ 2010-10-21 19:39 UTC (permalink / raw)
  To: Joshua Jensen; +Cc: git@vger.kernel.org


On Oct 21, 2010, at 2:47 PM, Joshua Jensen wrote:

> It has become a necessity to copy a file from one long-lived branch to another.  It is not possible to merge the branches at this time.
> 
> I would like to have 'git gui blame' follow the copy back through its original history, but I don't believe Git has metadata for storing this.  Something along the lines of a 'followparent' in the commit object, for instance, would allow the revision walking code to wander the history down an alternate line.

Git stores no per-file metadata.  The closest we come is .gitattributes and .gitignore.

> By comparison, integrates work at a file level in Perforce.  That means I can integrate a file from one branch to another, and parentage is stored such that I can follow the file back through its history.
> 
> Are there any facilities to do this now?

Git simply does not have the idea of the history of a file.  Nothing in git will help merge "just a file" from one branch to another.  Either we have merged the two commits or not.

HOWEVER...

You can use git-filter-branch to create a new branch that contains only that single file and only the commits that affected it.  Something like the following (untested):

	# Merging "file" from branch "src" to branch "dest"
	git checkout -b temp src
	git filter-branch --prune-empty --index-filter="git read-tree --empty; git add file"
	# Since you describe the branch as "long-running", I'd suspect you'll have to wait a while here.
	git checkout dest
	git merge temp
	git branch -d temp
	git branch -D refs/original/temp

This will go faster if you have a ramdisk/tmpfs to perform the filtering in.  (git-filter-branch is very I/O intensive.)  Something like the following in place of the `git filter-branch` invocation above:

	mkdir /tmp/filter-branch # Assuming /tmp is tmpfs or similar
	git filter-branch -d /tmp/filter-branch --prune-empty --index-filter="git read-tree --empty; git add file"
	rm -rf /tmp/filter-branch

You could use --msg-filter to add the SHA-1 of the original commits to the "file history" branch.  Something like --msg-filter='cat;echo;echo From: $GIT_COMMIT'

I would recommend using cherry-pick to pull any further changes to the file across branches (be careful of commits that touch more than that file!).  I think git-filter-branch could be used to keep the one file branch up to date, but that is likely more effort than it's worth.  I would specifically advise against merging the single file branch into both "src" and "dest", as I think any later merge of the two would find these commits as a merge-base.

~~ Brian Gernhardt

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Following history of a copied file from another indirect branch
  2010-10-21 19:39 ` Brian Gernhardt
@ 2010-10-21 20:06   ` Joshua Jensen
  0 siblings, 0 replies; 4+ messages in thread
From: Joshua Jensen @ 2010-10-21 20:06 UTC (permalink / raw)
  To: Brian Gernhardt; +Cc: git@vger.kernel.org

----- Original Message -----
From: Brian Gernhardt
Date: 10/21/2010 1:39 PM
> On Oct 21, 2010, at 2:47 PM, Joshua Jensen wrote:
>> It has become a necessity to copy a file from one long-lived branch to another.  It is not possible to merge the branches at this time.
>>
>> I would like to have 'git gui blame' follow the copy back through its original history, but I don't believe Git has metadata for storing this.  Something along the lines of a 'followparent' in the commit object, for instance, would allow the revision walking code to wander the history down an alternate line.
> Git stores no per-file metadata.  The closest we come is .gitattributes and .gitignore.
>
>> By comparison, integrates work at a file level in Perforce.  That means I can integrate a file from one branch to another, and parentage is stored such that I can follow the file back through its history.
>>
>> Are there any facilities to do this now?
> Git simply does not have the idea of the history of a file.  Nothing in git will help merge "just a file" from one branch to another.  Either we have merged the two commits or not.
I'm not super interested in per file merging (which is a great concept, 
works well in Perforce, but is irrelevant here).  I merely want to 
preserve the original parentage so facilities like blame (ultimately 
rev-list?) can walk the extended history.  I'm fine even passing in a 
flag.  I do not care in preserving the original parentage for purposes 
of merging.

> You can use git-filter-branch to create a new branch that contains only that single file and only the commits that affected it.  Something like the following (untested):
>
> I would recommend using cherry-pick to pull any further changes to the file across branches (be careful of commits that touch more than that file!).  I think git-filter-branch could be used to keep the one file branch up to date, but that is likely more effort than it's worth.  I would specifically advise against merging the single file branch into both "src" and "dest", as I think any later merge of the two would find these commits as a merge-base.
Thanks for the info.

The problem with using cherry-pick is that the commits in question 
contain more than one file.  Perhaps the individual file should have 
been committed separately, but the damage was long ago done.

git format-patch --stdout HEAD..otherbranch -- the/filename | git 
am           or
git diff HEAD..otherbranch -- the/filename | git apply

Seem to be the appropriate methods of copying the file over with fake 
history or squashed together.

Josh

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Following history of a copied file from another indirect branch
  2010-10-21 18:47 Following history of a copied file from another indirect branch Joshua Jensen
  2010-10-21 19:39 ` Brian Gernhardt
@ 2010-10-22  6:35 ` Johannes Sixt
  1 sibling, 0 replies; 4+ messages in thread
From: Johannes Sixt @ 2010-10-22  6:35 UTC (permalink / raw)
  To: Joshua Jensen; +Cc: git@vger.kernel.org

Am 10/21/2010 20:47, schrieb Joshua Jensen:
> It has become a necessity to copy a file from one long-lived branch to
> another.  It is not possible to merge the branches at this time.
> 
> I would like to have 'git gui blame' follow the copy back through its
> original history, but I don't believe Git has metadata for storing this. 
> Something along the lines of a 'followparent' in the commit object, for
> instance, would allow the revision walking code to wander the history down
> an alternate line.

You can branch off one commit form that long-lived branch that undoes
everything except the file F you are interested in since the last
merge-base. Then you merge that single commit into the other branch.

   ---o--o--B     <- long-lived
     /  /    \
    /  /      U   <- the-file
   /  /        \
 -o--A----------M <- master (the other branch)

i.e. 'git diff A..B' shows a lot of changes, but 'git diff A..U' shows
only changes to the file you are interested in. 'git diff -R B..U' differs
from 'git diff A..B' only in the changes to the file you are intersted in.

When you later find that you need new changes to F that were made on
long-lived, but you still cannot merge long-lived, then you can merge
long-lived into the-file (resolve conflicts by removing the conflicted
files and also remove newly added files), and then you merge the-file into
master again.

WARNING: When you later merge long-lived into master, the merge will lose
all changes made on long-lived. You work it around by temporarily grafting
away the merge parents that point to commits listed by
long-lived..the-file. After you complete the merge, you can remove the
grafts again.

-- Hannes

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-10-22  6:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-21 18:47 Following history of a copied file from another indirect branch Joshua Jensen
2010-10-21 19:39 ` Brian Gernhardt
2010-10-21 20:06   ` Joshua Jensen
2010-10-22  6:35 ` Johannes Sixt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).