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

Re: git filter-branch --subdirectory-filter

From
Johannes Sixt <j.sixt@viscovery.net>
Date
May 9, 2008, 07:57 UTC
Message-ID
<48240407.4080104@viscovery.net>
In-Reply-To
<e5e204700805090038k373bbabcyfb10d8c93ec5b3a7@mail.gmail.com>
James Sadler schrieb:
Show 32 quoted lines
> Hi Jeff,
> 
> After reading your reponse and re-reading my original email, I
> realised it was totally unclear
> so I have re-explained myself below.
> 
> 2008/5/9 Jeff King <peff@peff.net>:
>> On Fri, May 09, 2008 at 11:01:47AM +1000, James Sadler wrote:
>>> and ran filter-branch with a --commit-filter to skip commits that were
>>> irrelevant to th subdir.
>> But that's part of what subdirectory-filter does, so this step is
>> unnecessary.
> 
> Yes that's true, but...
> 
> Clearer explanation:
> 
> I originally tried --subdirectory-filter by itself to see if it would
> do the job, but it filtered
> more commits than I thought it should (some commits that touched the subdir were
> missing after filter-branch was run).
> 
> I then began to question my understanding of the semantics of
> subdirectory-filter.
> 
> Is it meant to:
> A) Only keep commits where ALL of the changes in the commit only touch
> content under $DIR?
> B) Only keep commits where SOME of the changes in the commit touch
> content under $DIR?
> 
> I suspected that it was behaving as A.
It's expected to do B.
Show 9 quoted lines
> That's when I decided to run the commit-filter first in combination
> with the tree-filter.  This would
> leave me with all commits that touched the subdir but any commit that
> touched multiple subdirs
> would be cleaned up so it only touched the subdir I want to keep.
> 
> At this point I have a bunch of commits that only make changes to
> subdir (verified using gitk), and I would
> expect subdirectory-filter to keep every single commit.
At this point you don't need subdirectory-filter. Use an --index-filter to
 keep only the subdirectory *and* remove the directory name at the same
time. Something like this:
git filter-branch --index-filter \
        'git ls-files -s thedir | sed "s-\tthedir/--" |
                GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                        git update-index --index-info &&
         mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD
> However, after running it, I loose most of my commits.  Strangely, the
> working tree is bit-for-bit correct
> with the original version or the subdir in the old repo, but the
> history leading up to it is not.

The bit-for-bit correctness is not surprising, but the incorrect history is. What is your definition of "correct" (i.e. can you give an example of your expectations that are not met)? Do you have complicated history (with merges)? Note that merges are removed if all but one of the merged branches do not touch the subdirectory.

-- Hannes
Previous: James SadlerNext: Jeff King
Message 4 of 10 in “git filter-branch --subdirectory-filter”
  1. James SadlerMay 9, 2008
  2. Jeff KingMay 9, 2008
  3. James SadlerMay 9, 2008
  4. Johannes SixtMay 9, 2008
  5. Jeff KingMay 9, 2008
  6. James SadlerMay 10, 2008
  7. Jeff KingMay 10, 2008
  8. James SadlerMay 10, 2008
  9. James SadlerMay 10, 2008
  10. Jeff KingMay 10, 2008

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.