Search code examples
gitrenamemv

I have two .git directories for one project/folder, how do I rename a file in working tree?


For some reason, I followed https://stackoverflow.com/a/17313342/4336225 to get .gitone and .gittwo. Now I need to rename a file in my working directory. Classically, I would use

git mv application.py newApplication.py

But how do I do it now with two .git? I want both of them to track the name change properly.


Solution

  • As shown in the linked answer, you should use the --git-dir option.

    git --git-dir=.gitone mv application.py newApplication.py


    Edit

    Here is a complete walkthrough

    
    $ # Create multiple git directories
    $ git init .
    Initialized empty Git repository in /tmp/so_git/.git/
    
    $ mv .git .gitone
    
    $ git init .
    Initialized empty Git repository in /tmp/so_git/.git/
    
    $ mv .git .gittwo
    
    $ # Add a file to both directories
    $ touch foo
    
    $ git --git-dir=.gitone add foo
    
    $ git --git-dir=.gitone commit -m "add foo"
    [master (root-commit) 0db71dc] add foo
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 foo
    
    $ git --git-dir=.gittwo add foo
    
    $ git --git-dir=.gittwo commit -m "add foo"
    [master (root-commit) 10205ba] add foo
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 foo
    
    $ # Move file in first git repo
    $ git --git-dir=.gitone mv foo bar
    
    $ git --git-dir=.gitone commit -m "foo -> bar"
    [master 20276ee] foo -> bar
     1 file changed, 0 insertions(+), 0 deletions(-)
     rename foo => bar (100%)
    
    $ # File is marked as deleted in second repo while "bar" is untracked
    $ git --git-dir=.gittwo status
    On branch master
    Changes not staged for commit:
      (use "git add/rm <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
        deleted:    foo
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
        .gitone/
        .gittwo/
        bar
    
    no changes added to commit (use "git add" and/or "git commit -a")
    
    $ # Add "bar" to the tracked files
    $ git --git-dir=.gittwo add bar
    
    $ git --git-dir=.gittwo status
    On branch master
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
        new file:   bar
    
    Changes not staged for commit:
      (use "git add/rm <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
        deleted:    foo
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
        .gitone/
        .gittwo/
    
    $ # Explicitly delete foo
    $ git --git-dir=.gittwo rm foo
    rm 'foo'
    
    $ # Now git discovered the rename
    $ git --git-dir=.gittwo status
    On branch master
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
        renamed:    foo -> bar
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
        .gitone/
        .gittwo/
    

    Another solution if you want to use git mv instead of git [add|rm], is to checkout back you foo file and force move it to bar.

    $ git --git-dir=.gitone commit -m "foo -> bar"
    [master 20276ee] foo -> bar
     1 file changed, 0 insertions(+), 0 deletions(-)
     rename foo => bar (100%)
    
    $ git --git-dir=.gittwo checkout -- foo
    
    $ git --git-dir=.gittwo mv -f foo bar
    
    $ git --git-dir=.gittwo status
    On branch master
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
        renamed:    foo -> bar
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
        .gitone/
        .gittwo/