threads / discuss / 14555

making a branch with just one file and keeping its whole history

Subject: making a branch with just one file and keeping its whole history

## tl;dr

7 messages between Jul 21, 2008 and Jul 22, 2008.

replies: 6people: 4as markdown or json

ncrfgs@tin.it· Jul 21, 2008, 04:18 UTC · lore
Hi,

I have a working local repository and I'd like to make a branch with just one file (let's say path2/filename2) and to keep its whole history.

At first I've considered creating a fresh new repo and redirecting `git-log -p --follow path2/filename2` output to some other git command.

When later I've discussed the topic on #git@irc.freenode.net I've been pointed to git-filter-branch.

Searching for more info about git-filter-branch on the web I've found a couple of examples that might be close to what I'd like to accomplish:

from http://loupgaroublond.blogspot.com/2007/12/how-to-split-repository-in-git.html
	$ git filter-branch --tree-filter 'rm -rf $put_the_files_you_want_to_remove_here' HEAD
	$ git reset --hard
	$ git gc --aggressive
	$ git prune
from http://log.emmanuelebassi.net/archives/2007/09/when-the-levee-breaks/
	$ git clone --no-hardlinks /tmp/gtk2-perl Gtk2-SourceView.git
	$ git filter-branch --subdirectory-filter Gtk2-SourceView HEAD
	$ git reset --hard
	$ git gc --aggressive
	$ git prune
I've also gone through man pages and I've found something interesting:
	$ git-filter-branch --tree-filter 'rm $filename' HEAD
or, as far as I understood, equivalent and faster:
	$ git-filter-branch --index-filter 'git-update-index --remove $filename' HEAD 

Now, what I'd like to do is complementary to the above example; the difference is that I don't want to remove just one file and its traces from history; rather I'd like to have a new repo which includes just that file and its history.

So I would need something like the following command:
	$ git-filter-branch --tree-filter 'keep(?) $filename' HEAD
I think one possible solution would be:
	$ git-filter-branch --tree-filter 'find ! -type d | grep -v "^./path2/filename2$" | while read FILE; do rm $FILE; done' HEAD
Problems come, I think, if the content you want to keep track of, is placed in a
file that has been renamed. For example, let's say that the content you want to
keep track of was in:
	path1/filename1 from commit 1 to commit 1000
	path2/filename1 from commit 1001 to commit 2000
	path2/filename2 from commit 2001 to commit 3000
In this case I think one possible solution would be:
	$ git-filter-branch --tree-filter 'find ! -type d | grep -v "^./path1/filename1$" | grep -v "^./path2/filename1$" | grep -v "^./path2/filename2$" | while read FILE; do rm $FILE; done' HEAD

But what happens if in the meanwhile a new file has been created with one of the names we used for the content we want to keep track of? Let's say, following the previous case, that path2/filename1 has been renamed to path2/filename2 with commit 2001, and that with commit 2500 a new file has been created with name path1/filename1.

Considering both the solutions I've found on the web and the ones I've been
suggested on #git@irc.freenode.net I've found four/five possible path to follow:
	a) git log | another git command (later I've been told that git log --follows leaves out the initial revision)
	b) git clone; git filter-branch
	c) create a new repo with your one file and make an initial commit
	   then do: (cd repo-with-one-file; git ls-tree)|(cd repo-where-you-want-the-new-branch; git-mktree)
	d) git commit-tree that-tree < file-with-commit-message
	   then: git checkout -b branchname that-commit
	e) git-am or git apply processing the output of git-log or another
	   similar command
I hope you guys can help me to make some light on this issue.
Thanks in advance. :D

P.S. Sorry for my bad english but I'm not a native english speaker, I hope that what I've written made enough sense to you. :)

Eric Raible· Jul 21, 2008, 16:19 UTC · re: ncrfgs@tin.it · lore

Re: making a branch with just one file and keeping its whole history

 <ncrfgs <at> tin.it> writes:
Show 5 quoted lines
> 
> Hi,
> 
> I have a working local repository and I'd like to make a branch with just one
> file (let's say path2/filename2) and to keep its whole history.
http://www.gitcasts.com/posts/empty-branches
- Eric
Johannes Schindelin· Jul 21, 2008, 18:08 UTC · re: Eric Raible · lore

Re: making a branch with just one file and keeping its whole history

Hi,
On Mon, 21 Jul 2008, Eric Raible wrote:
Show 7 quoted lines
>  <ncrfgs <at> tin.it> writes:
> 
> > I have a working local repository and I'd like to make a branch with 
> > just one file (let's say path2/filename2) and to keep its whole 
> > history.
> 
> http://www.gitcasts.com/posts/empty-branches

Beware! This is one of the sites that triggered my mail about considering teaching plumbing to new users harmful.

In other words, I think that these "git casts" are not really the best way to teach Git to new users, but rather confusing.

Which is a pity, because they are nicely done otherwise.

Ciao, Dscho

Eric Raible· Jul 21, 2008, 18:22 UTC · re: Johannes Schindelin · lore

Re: making a branch with just one file and keeping its whole history

On Mon, Jul 21, 2008 at 11:08 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

Show 15 quoted lines
>
> On Mon, 21 Jul 2008, Eric Raible wrote:
>
>> http://www.gitcasts.com/posts/empty-branches
>
> Beware!  This is one of the sites that triggered my mail about considering
> teaching plumbing to new users harmful.
>
> In other words, I think that these "git casts" are not really the best way
> to teach Git to new users, but rather confusing.
>
> Which is a pity, because they are nicely done otherwise.
>
> Ciao,
> Dscho

I understand your concern, but if you treat that particular gitcast simple as a recipe to be followed it accomplishes the goal in the in the most straightforward way I've seen.

A new-user pure-porcelain way would be to branch then delete all of the files in the branch. Which seems a bit dirty to me.

Or is there some more intuitive porcelain-ish way of creating a new empty branch that I haven't thought of?

- Eric
Johannes Schindelin· Jul 21, 2008, 18:39 UTC · re: Eric Raible · lore

Re: making a branch with just one file and keeping its whole history

Hi,
On Mon, 21 Jul 2008, Eric Raible wrote:
Show 18 quoted lines
> On Mon, Jul 21, 2008 at 11:08 AM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> >
> > On Mon, 21 Jul 2008, Eric Raible wrote:
> >
> >> http://www.gitcasts.com/posts/empty-branches
> >
> > Beware!  This is one of the sites that triggered my mail about considering
> > teaching plumbing to new users harmful.
> >
> > In other words, I think that these "git casts" are not really the best way
> > to teach Git to new users, but rather confusing.
> >
> > Which is a pity, because they are nicely done otherwise.
> 
> I understand your concern, but if you treat that particular gitcast 
> simple as a recipe to be followed it accomplishes the goal in the in the 
> most straightforward way I've seen.

Note, I haven't even bothered to watch that Gitcast, since it would make me mad again.

> A new-user pure-porcelain way would be to branch then delete all of the 
> files in the branch.  Which seems a bit dirty to me.

This will not start a new branch, which is what I presume you want to do. The "correct" (as in: probably the best) way to do it is to make a new directory, initialize a new git repository in it, and when you have something, push that branch into the other repository.

However, I think that the OP was talking about something completely different: extracting the history of a single file as a new branch.

Ciao, Dscho

ncrfgs@tin.it· Jul 22, 2008, 02:14 UTC · re: Johannes Schindelin · lore

extracting the history of a single file as a new project [Was: Re: making a branch with just one file and keeping its whole]

On Mon, 21 Jul 2008 20:39:45 +0200 Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

> However, I think that the OP was talking about something completely 
> different: extracting the history of a single file as a new branch.
Exactly, but rather than a new branch I'd like to start a new project.

I've just realized the original subject name could have been a bit misleading; I took it from the description a guy on #git@freenode has given of what he thought I wanted to do, but probably I didn't explain myself properly at that time.

> This will not start a new branch, which is what I presume you want to
> do. The "correct" (as in: probably the best) way to do it is to make a
> new directory, initialize a new git repository in it, and when you
> have something, push that branch into the other repository.

As far as I could understand, that screencast demonstrates how to create empty branches in Git; in other words branches that are not derivatives of your main branches, but entirely new projects.

In my case I don't want to start an entirely new project, but rather start a new project from a file of an existing project and keeping his history.

In the screencast, the author creates an empty branch to store the website code in for my project, so he doesn't have to store it as a subdirectory of his main project.

What I want to do, I think, is kinda different.

Let's say we are at commit #3000, I have this content I want to start a new project from, which has been put in three different files:

path1/filename1 from commit 1 to commit 1000 path2/filename1 from commit 1001 to commit 2000 path2/filename2 from commit 2001 to commit 3000

In the meanwhile path1/filename1 has been created on commit 2500 with path1/filename1 having nothing to do with the new project I'd like to start.

My first idea to accomplish what I'd like to do, was to use the ouput of `git-log -p --follow path2/filename2` with another git command; on #git@freenode I've been suggested to use git-clone and git-filter-branch.

Both from search results on the web and from the man pages, I've found examples of git-filter-branch usage which aim to delete just one file (or a small group of files) from the existing project's history.

What I'd like to do instead is to keep just one file which has been renamed a couple of time.

On #git I've been also told to use also another combination of commands which included git-commit-tree but I haven't managed to understand what they meant. Another combination of commands included git-am instead.

Any suggestion is welcome. :)
Sverre Rabbelier· Jul 22, 2008, 06:15 UTC · re: ncrfgs@tin.it · lore

Re: extracting the history of a single file as a new project [Was: Re: making a branch with just one file and keeping its whole]

On Tue, Jul 22, 2008 at 4:14 AM,  <ncrfgs@tin.it> wrote:
Show 10 quoted lines
> Let's say we are at commit #3000, I have this content I want to start a
> new project from, which has been put in three different files:
>
> path1/filename1 from commit 1 to commit 1000
> path2/filename1 from commit 1001 to commit 2000
> path2/filename2 from commit 2001 to commit 3000
>
> In the meanwhile path1/filename1 has been created on commit 2500 with
> path1/filename1 having nothing to do with the new project I'd like to
> start.
<snip>
Show 5 quoted lines
> My first idea to accomplish what I'd like to do, was to use the ouput of
> `git-log -p --follow path2/filename2` with another git command; on
> #git@freenode I've been suggested to use git-clone and
> git-filter-branch.
>

It would seem that this is a valid use-case for a properly working "git log --follow", yes?

-- 
Cheers,

Sverre Rabbelier

← back to recent threads