Skip to content

Instantly share code, notes, and snippets.

@ajaegers
Last active February 17, 2024 13:28
Show Gist options
  • Save ajaegers/2a8d8cbf51e49bcb17d5 to your computer and use it in GitHub Desktop.
Save ajaegers/2a8d8cbf51e49bcb17d5 to your computer and use it in GitHub Desktop.
Git: move files in an subfolder keeping history

Change structure of project folder with Git

I have this structure:

 project-folder/
     .git
     wp-admin/
     wp-content/
     wp-includes/
    .htaccess
    ...

I want this structure:

 project-folder/
     .git
     public
          wp-admin/
          wp-content/
          wp-includes/
         .htaccess
         ...

The benefits

  • Keep away from the Internet my .git folder
  • Wordpress files separated in a sub-folder
  • Keep Git history changes
  • Hide from the Internet deployment scripts or project sensitive informations

Move files with git and keep file history

  1. Be sure you don't have files uncommitted, if not commit them before next step.

    git status

  2. In project-directory create public subfolder

    mkdir public

  3. Move files with git mv except public subfolder to avoid errors

    for file in $(ls | grep -v 'public'); do git mv $file public; done;

  4. Move specific files like .htaccess etc...

    git mv .htaccess public/

  5. Commit changes

    git commit -m 'Moved files to public/'

  6. That's all !

    git log -M summary

To see file history of moved files

In Bash:

git log --follow

http://git-scm.com/docs/git-log

In SourceTree:

On logging file(s) you have to check [x] Follow renamed files

@imsandeepsharma
Copy link

getting an error:- file was unexpected at this time.

@sukhithaIvolve
Copy link

getting an error:- file was unexpected at this time.

Try GitBash. Not CMD.

@gpoole
Copy link

gpoole commented Sep 28, 2021

If you're coming to this gist from Google looking for "the right way" to rename files while retaining git history, the title is a bit misleading:

Move files with git and keep file history

Nothing in the steps especially helps keep the history intact, it's just relying on git log --follow like any other time you move files. The git mv command used in step 3 doesn't do anything special:

Git has a rename command git mv, but that is just for convenience. The effect is indistinguishable from removing the file and adding another with different name and the same content.

I'd guess most people looking at this have already had problems with git log --follow not working for them, so just a heads up this isn't going to solve that problem for you. Unfortunately there's no "correct" way to do this with git. Really the only way to get what you probably want is if you're willing to rewrite your entire history via a rebase, for example using something like this: https://gist.github.com/emiller/6769886 (risky move, be careful!)

Sorry to be critical, just thought it was worth the clarification since this was the top result on Google for me for this question.

@cxgreat2014
Copy link

cxgreat2014 commented May 4, 2022

Move files with git and keep file history

Nothing in the steps especially helps keep the history intact, it's just relying on git log --follow like any other time you move files. The git mv command used in step 3 doesn't do anything special:

But git mv seems like work on Windows 10.

If I move file in windows explorer, git will not track, but use git mv work.

@gpoole
Copy link

gpoole commented May 4, 2022

I'm not sure what specific problem it's solving with Explorer, but as far as the actual tracking of renames through Git history is concerned, git mv functionally equivalent to:

mv path/to/old/file path/to/new/file
git add path/to/new/file
git rm path/to/old/file

In terms of being able to follow the history of a file through renames in Git, neither approach do a better job.

@talkingtoaj
Copy link

I concur with @cxgreat2014 , testing it myself on a windows system, the key points of interest are:

  1. open the project folder with gitbash in order to avail yourself of linux
  2. use the for file in $(ls | grep -v 'public'); do git mv $file public; done; line, substituting public with the name of your new folder
  3. upon reopening my terminal in this folder, I see a message from git written in blue stating * History restored
  4. I find git now has all moved files staged for a commit, marked as 'renamed'. I make a new commit of these renames, and I find I have my old git history intact with only an additional commit added to my repo. Great work @ajaegers !

@Binly42
Copy link

Binly42 commented Feb 17, 2024

Unfortunately there's no "correct" way to do this with git. Really the only way to get what you probably want is if you're willing to rewrite your entire history via a rebase

note that the original source of the reference link might be: this stackoverflow answer,

and after some reading and digging, I just take a little notes here:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment