* 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).