0

I've a multi-branches repo in foo/src , however I want to move the repo up (.git becomes a neighbor to src) while preserving history and add all these files to the whole history.

--- foo/  
      |-bar/  
      |-src/
           |-.git
      |-hello.txt

How can I do that ?

Note : I've tried this answer, But couldn't add files to the whole repo history. I then tried rebase -i --root (here) but that only applied to one branch, corrupts and outdated the rest.

Hugo y
  • 1,421
  • 10
  • 20
Hamza Hajeir
  • 119
  • 1
  • 8

1 Answers1

1

BEFORE YOU START: Make a backup of your git repo because the filter-branch command is destructive!


You could use git filter-branch with the --tree-filter option. The manual for the --tree-filter options states:

This is the filter for rewriting the tree and its contents. The argument is evaluated in shell with the working directory set to the root of the checked out tree. The new tree is then used as-is (new files are auto-added, disappeared files are auto-removed - neither .gitignore files nor any other ignore rules HAVE ANY EFFECT!).

So for each commit we want to create a new directory src and move all files in the tree to it (excluding src/ itself of course).

git filter-branch --tree-filter '
mkdir -p src
for i in *; do
    if [ "$i" != "src" ]; then
        mv "$i" src/
    fi
done
' --all

The afterwards you can add the untracked bar/ directory and hello.txt as a new commit on top.

If you want bar/ and hello.txt to be present in the repo from the start of the history, you will have to adjust the tree filter command slightly.

git filter-branch --tree-filter '
mkdir -p src
for i in *; do
    if [ "$i" != "src" ]; then
        mv "$i" src/
    fi
done
cp -R "/path/to/bar" .
cp "/path/to/hello.txt" .
' --all
Henri Menke
  • 10,705
  • 1
  • 24
  • 42
  • Thanks, I've tried this command, It doesn't include other files into the history : bar/ and hello.txt – Hamza Hajeir Jan 12 '20 at 22:03
  • @HamzaHajeir Well, of course, because according to the description in your question only the files in the `src/` directory are tracked. So using the command in my answer, you can manipulate the tree such that everything appear in the `src/` subdirectory and then you can add the untracked `bar/` and `hello.txt`. – Henri Menke Jan 12 '20 at 23:00
  • @HamzaHajeir Does my updated answer suit your needs? – Henri Menke Jan 12 '20 at 23:13
  • Hi @Henri, Thanks for the answer.. first it didn't apply to all branches, so I added -- --all before HEAD and it works well. please edit the answer to match this. – Hamza Hajeir Jan 18 '20 at 18:10
  • Some things to consider for readers : I had another repos inside `bar`, Couldn't copy them. (fixed by adding git links to project dependency : private case) .. second thing : I had one **tag** in my history. I missed to add `--tag-name-filter cat` so it's not rewritten. – Hamza Hajeir Jan 18 '20 at 18:14
  • @HamzaHajeir I've added `--all` to the examples. – Henri Menke Jan 19 '20 at 00:15
  • Good,, I don't know if it's mandatory to prefix `--all` with two dashes or not .. i e `-- --all` but what I tried is the one with 2 dashes... Thanks for your help @Henri – Hamza Hajeir Jan 20 '20 at 22:07