Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to move a folder from one repo to another and keep its commit history
# source: http://st-on-it.blogspot.com/2010/01/how-to-move-folders-between-git.html
# First of all you need to have a clean clone of the source repository so we didn't screw the things up.
git clone git://server.com/my-repo1.git
# After that you need to do some preparations on the source repository, nuking all the entries except the folder you need to move. Use the following command
git filter-branch --subdirectory-filter your_dir -- -- all
# This will nuke all the other entries and their history, creating a clean git repository that contains only data and history from the directory you need. If you need to move several folders, you have to collect them in a single directory using the git mv command.
# You also might need to move all your content into some directory so it didn't conflict with the new repository when you merge it. Use commands like that
mkdir new_directory/
git mv my_stuff new_directory/
# Once you've done commit your changes, but don't push!
git commit -m "Collected the data I need to move"
# This is all about the source repository preparations.
# Now go to your destination repository
cd ../my-repo2/
# And here is the trick. You need to connect your source repository as a remote using a local reference.
git remote add repo1 ../my-repo1/
# After that simply fetch the remote source, create a branch and merge it with the destination repository in usual way
git fetch repo1
git branch repo1 remotes/repo1/master
git merge repo1 --allow-unrelated-histories
# This is pretty much it, all your code and history were moved from one repository to another. All you need is to clean up a bit and push the changes to the server
git remote rm repo1
git branch -d repo1
git push origin master
# That's all. After that you can nuke the temporary source repository.
@sudhirshahu51

This comment has been minimized.

Copy link

@sudhirshahu51 sudhirshahu51 commented Jul 2, 2017

I am facing a problem with this please tell me where is repo1 present i.e. on my actual git repository or at the local system?. please help me out I am too confused with this.
image

@recyclerobot

This comment has been minimized.

Copy link

@recyclerobot recyclerobot commented Aug 7, 2017

@trongthanh from git 2.9 you'll need to do git merge repo1 --allow-unrelated-histories (line 35)

@Romeus

This comment has been minimized.

Copy link

@Romeus Romeus commented Aug 31, 2017

@sudhirshashu51 Have exactly the same problem

@robin-carry

This comment has been minimized.

Copy link

@robin-carry robin-carry commented Sep 12, 2018

Rock star article :)

@marcellanz

This comment has been minimized.

Copy link

@marcellanz marcellanz commented Mar 8, 2019

@sudhirshahu51 your first command failed as by the "usage" error git displays. you called "git remote add" with three arguments (repo, ../Python-programming-Udacity and /) but you can only supply 2 (, ) as by the git command stated. So for sure, the next command (git fetch repo1) also fails.

For help I suggest to provide more context, what you did and what you have. And during the session of what you did, have a eye to errors or message you get from git that shows any error. This helps to find which commands you issued failed and why.

@jpop32

This comment has been minimized.

Copy link

@jpop32 jpop32 commented Apr 30, 2019

This failed (git version 2.16.2):

git merge repo1

with

fatal: refusing to merge unrelated histories

needed to include the switch

git merge repo1 --allow-unrelated-histories

and the rest went without any problems.

@flakrat

This comment has been minimized.

Copy link

@flakrat flakrat commented Jun 11, 2019

+1 to @jpop32 I was just about to comment about the need for --allow-unrelated-histories

@trongthanh

This comment has been minimized.

Copy link
Owner Author

@trongthanh trongthanh commented Jun 12, 2019

Added --allow-unrelated-histories to the Gist as per above comments

@gibello

This comment has been minimized.

Copy link

@gibello gibello commented Aug 16, 2019

Works like a charm, thanks a lot :)

@nhmaha

This comment has been minimized.

Copy link

@nhmaha nhmaha commented Aug 24, 2019

Thanks a lot. it works.

@IlDordollano

This comment has been minimized.

Copy link

@IlDordollano IlDordollano commented Sep 3, 2019

Works perfectly!

I would add a little clarification:

Use git branch repo1 remotes/repo1/master only if the folder that you want to move belongs to the master branch of repo1. If the folder is on another branch, you must type git branch repo1 remotes/repo1/branch_with_folder

@joelvh

This comment has been minimized.

Copy link

@joelvh joelvh commented Sep 10, 2019

I also wanted to keep multiple folders and files, so I used this command instead of git filter-branch --subdirectory-filter:

git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- dir1 dir2' --prune-empty -- --all

via Stack Overflow

@rohitsalem

This comment has been minimized.

Copy link

@rohitsalem rohitsalem commented Oct 9, 2019

Thanks!

@tuxmaster5000

This comment has been minimized.

Copy link

@tuxmaster5000 tuxmaster5000 commented Oct 25, 2019

Very nice, but it fails with signed history's.
After that procedure, all gpg signatures are lost.

@tuxmaster5000

This comment has been minimized.

Copy link

@tuxmaster5000 tuxmaster5000 commented Oct 25, 2019

As an workaround:
After filter in the destination repo use this:
https://gist.github.com/qdequele/490e413f82ab16e640510c180bb99b5b

@philipsparrow

This comment has been minimized.

Copy link

@philipsparrow philipsparrow commented Jan 23, 2020

Thank you this worked perfectly for me.
I thought git filter-branch --subdirectory-filter your_dir -- -- all with the -- -- was a typo but it is correct (another piece of git magic)

@MaikoKingma

This comment has been minimized.

Copy link

@MaikoKingma MaikoKingma commented Feb 27, 2020

Very useful article. I also want to move the folder to a specific location within the new repository.

Example:
old_repo/your_dir
new_repo/other_folder/your_dir

Any advice on how to move the contents of your_dir to the location in the new repository?

@itsmeabhijeet

This comment has been minimized.

Copy link

@itsmeabhijeet itsmeabhijeet commented May 7, 2020

Can someone advice how to do the following
Move all files and directories of repo1 to repo2/test/ with preserving the history of repo1.

@MaikoKingma

This comment has been minimized.

Copy link

@MaikoKingma MaikoKingma commented May 8, 2020

@itsmeabhijeet you can skip git filter-branch and create the test directory in repo1 before moving. Your example would look like this:

git clone git://server.com/my-repo1.git
mkdir test/
git mv everything test/
git commit -m "Collected the data I need to move"
// Continue original script
@itsmeabhijeet

This comment has been minimized.

Copy link

@itsmeabhijeet itsmeabhijeet commented May 8, 2020

@MaikoKingma : Thanks for the response.
But in the target repo i.e repo2, i want the source repo to be moved inside a sub-directory. for example the end result should be repo2/test/repo1.
In this case should i try to execute the commands from repo2/test ?

when i try at repo2 ( cd repo2), all the files are fetched under repo2. Also when i move inside repo2/test/ , i get git errors.

Could you please help or provide full commands. My requirements is kind of similar like your earlier post. Thanks in Advance

@itsmeabhijeet

This comment has been minimized.

Copy link

@itsmeabhijeet itsmeabhijeet commented May 9, 2020

Adding repo1 to a sub directory inside repo2 seems tricky. Please advice.
End result should be something like repo2/dir1/repo1. Thanks in advance.

@keithb95

This comment has been minimized.

Copy link

@keithb95 keithb95 commented May 12, 2020

Take a look at "git filter-repo". Most posts are many years old - this is the latest solution that works great, and is recommended by GIT.

@watery

This comment has been minimized.

Copy link

@watery watery commented May 27, 2020

Thanks, worked like a charm.

Can I keep using this procedure continuously? I mean, can I still develop in my-repo1 and periodically merge into my-repo2, or is this a one time only operation? And would that still be possible if other commits are added to my-repo2 between the merges?

@RJVB

This comment has been minimized.

Copy link

@RJVB RJVB commented Aug 22, 2020

@itsmeabhijeet you can skip git filter-branch and create the test directory in repo1 before moving. Your example would look like this:

git clone git://server.com/my-repo1.git
mkdir test/
git mv everything test/
git commit -m "Collected the data I need to move"
// Continue original script

Except that this essentially cuts off the history for the items you want to keep!

@alladinUK

This comment has been minimized.

Copy link

@alladinUK alladinUK commented Sep 15, 2020

Hi,
I've tested this against a test repo and it worked, thank you, however I have a few questions;

  1. In the script you create new_directory and move stuff into it. In my case this "stuff" needs to reside in the root, however, git merge repo1 --allow-unrelated-histories commits new_directory/my_stuff1, new_directory/my_stuff2 where it should be /my_stuff1 /my_stuff2. How can I make this happen?
  2. I'm a newbie to all this, after completing all the steps in your script, do you delete everything in the folder and restore the cloned folder then delete the folders i've moved to the new repo?
  3. I have multiple features, develop and master branches, do I have to repeat the whole process for each branch?

For example repeat your steps but changing the following based on the branch;

git clone git://server.com/my-repo1.git (against develop branch)
git branch repo1 remotes/repo1/master
git push origin develop


git clone git://server.com/my-repo1.git (against master branch)
git branch repo1 remotes/repo1/master
git push origin master

git clone git://server.com/my-repo1.git (against feature1 branch)
git branch repo1 remotes/repo1/master
git push origin features/feature1

feature2
feature3...

@cvila84

This comment has been minimized.

Copy link

@cvila84 cvila84 commented Nov 18, 2020

thank you very much for this ! you made my day :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.