2

I want to rewrite history and move all files and folders in a certain folder 2 folders up for all branches.

My repo looks like:

  • src
    • v105
    • src
      • files
      • folders
  • tools
  • lib

I want it to be:

  • src
    • files
    • folders
  • tools
  • lib

I know how to rewrite history for removing files recursively in a folder

git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatched somefolder/somefolder' --prune-empty --tag-name-filter cat -- --all

I also know the git mv command.

Using the following command the files and folders are all moved to the correct folder. The first patterns matches all files and folders within the provided folder. The second pattern matches all files and folders starting with a dot.

git mv src/v105/src/* src/v105/src/.[^.]* src

However when I want to use this command with the rewrite history command it doesn't work.

git filter-branch --force --index-filter 'git mv src/v105/src/* src/v105/src/.[^.]* src --cached --ignore-unmatched' --prune-empty --tag-name-filter cat -- --all

Because the src folder does not exist in all cases in my commit history it tells me it can't find the src dir. Any ideas how to solve this?

UPDATE

git filter-branch --force --index-filter 'if [-d 'src/v105/'] then git mv src/v105/src/* src/v105/src/.[^.]* src fi' --prune-empty --tag-name-filter cat -- --all results in unexpected end of file.

interestedparty333
  • 2,386
  • 1
  • 21
  • 35
Marco
  • 4,817
  • 5
  • 34
  • 75
  • Why do you need to rewrite history? And in any case, can't you just copy the files and then call filter-branch to remove the old location? – adamdunson May 08 '13 at 21:46
  • 1
    Because I am cleaning up the repo. I want it to become smaller, so I don't want my cleanup actions to be new commits. – Marco May 09 '13 at 09:04

2 Answers2

3

The filter commands don't need to be git commands. Could it be as simple as this?

git filter-branch --force --tree-filter 'mv src/src/files src/; mv src/src/folders src/'

Yarek T
  • 9,715
  • 2
  • 28
  • 38
Gary Fixler
  • 5,632
  • 2
  • 23
  • 39
  • Did you give it a try (on a clone of your repo, for safety)? It worked for me, though it doesn't seem as solid as the 3rd example here: http://stackoverflow.com/a/3142821/955926 - you could run it in two passes: `git filter-branch --tree-filter 'test -d src/src/files && mv src/src/files . || echo " Nothing to do"' HEAD`, then again changing files to folders. – Gary Fixler May 09 '13 at 11:29
  • I just got it working manually, updated my question... I need the --index-filter and --prune-empty --tag-name-filter cat -- --all because I want to do it on all branches – Marco May 09 '13 at 11:43
0

With regards to the "unexpected end of file" error, I think you forgot to add semicolons after each statement. git-filter-branch should then work.

git filter-branch --force --index-filter 'if [-d "src/v105/"]; then git mv src/v105/src/* src/v105/src/.[^.]* src; fi' --prune-empty --tag-name-filter cat -- --all

However, you'll start seeing the error [-d: command not found. This is easily fixed by adding in the appropriate whitespace within the [ expression.

git filter-branch --force --index-filter 'if [ -d "src/v105/" ]; then git mv src/v105/src/* src/v105/src/.[^.]* src; fi' --prune-empty --tag-name-filter cat -- --all

And that should work!

sbrun
  • 197
  • 2
  • 13