git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: import files w/ history

From
Jeff King <peff@peff.net>
Date
Mar 8, 2009, 00:10 UTC
Message-ID
<20090308001021.GA26167@coredump.intra.peff.net>
In-Reply-To
<slrngr299k.1t4t.csaba-ml@beastie.creo.hu>
On Fri, Mar 06, 2009 at 01:29:38PM +0000, Csaba Henk wrote:
Show 7 quoted lines
> $ git filter-branch --commit-filter '
>    if [ $# -lt 3 ] || git diff --stat $3 $1 | grep -q 'sys/dev/disk/vn/vn\.c'
>    then
>      git commit-tree "$@"
>    else
>      skip_commit "$@"
>    fi' HEAD
Wow, I'll bet that was slow to run. And it's not really what you want.

You are picking commits that changed a particular file, and then including the _whole_ tree. Remember that commits really record a tree state; we only think of them as "changes" because they point to a prior commit with its own tree state. So you are just selecting some subset of the states, but not cutting down the tree in each state.

What you really want to do is say:
  - for every commit, narrow the tree to _just_ the one file
  - if there were no changes in the narrowed tree, just throw out the
    commit

You can use an --index-filter to do the former, and a --commit-filter to do the latter (or just use --prune-empty, which is a shorthand).

Another poster had a similar problem, and you can see the right filter-branch recipe there:

  http://article.gmane.org/gmane.comp.version-control.git/111991
Show 21 quoted lines
>   *  *  *
> 
> OK, I then tried to do more RTFM and be more clever and efficient, and
> find a way to specify directly those commits which affect vn.c. As "git
> rev-list" can be invoked like "git rev-list <commit> <path>", and the
> synopsis of "git filter-branch" is like
> 
>  git filter-branch [options] [--] [<rev-list options>...]
> 
> I then gave a try to:
> 
> $ git filter-branch --  master sys/dev/disk/vn/vn.c
> 
> but no dice -- I got:
> 
>   fatal: ambiguous argument 'sys/dev/disk/vn/vn.c': unknown revision or
>   path not in the working tree.
>   Use '--' to separate paths from revisions
>   Could not get the commits
> 
> Any idea?

I think you need an extra '--' to separate the paths from the revisions in the rev-list arguments:

  git filter-branch -- master -- sys/dev/disk/vn/vn.c

but even that doesn't quite do what you want. It limits the commits that are shown, similar to your first attempt above, but it doesn't cut down the tree itself (OTOH, limiting by path rather than using --prune-empty is likely to run faster, since you won't even look at commits that are uninteresting. However, it may change the shape of your history with respect to branching and merging).

-Peff
Previous: Miklos VajnaNext: Csaba Henk
Message 5 of 8 in “import files w/ history”
  1. Csaba HenkMar 3, 2009
  2. Jeff KingMar 3, 2009
  3. Csaba HenkMar 6, 2009
  4. Miklos VajnaMar 6, 2009
  5. Jeff KingMar 8, 2009
  6. Csaba HenkMar 9, 2009
  7. Jeff KingMar 10, 2009
  8. Csaba HenkMar 11, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.