Git: Copy a file or directory from another repository preserving the history

How to copy a file or directory from another GIT repository while preserving its history?

Internet is full of magic formulas each one more complex.

Here I’m proposing a much simpler and faster one that is to make a git format-patch for the entire history of the file or subdirectory that we want and then import it into the destination repository.

mkdir /tmp/mergepatchs
cd ~/repo/org
export reposrc=myfile.c #or mydir
git format-patch -o /tmp/mergepatchs $(git log $reposrc|grep ^commit|tail -1|awk '{print $2}')^..HEAD $reposrc
cd ~/repo/dest
git am /tmp/mergepatchs/*.patch

Simple and fast :)

Leave a comment ?

11 Comments.

  1. Nice solution! I’m stealing this.

  2. Now that I will be using this for the fourth time I have to say a quick thanks for the brilliant tip. :)

  3. I’m using it as a little script: https://gist.github.com/voltagex/3888364

    Thanks very much for this, it’s pretty useful.

  4. This does not work if the file was made in the initial commit. To check this, run:


    INITCOMMIT=$(git rev-list --parents HEAD | egrep "^[a-f0-9]{40}$")
    git show $INITCOMMIT

    If this is the case, replay the initial commit to get the above code to work like before:


    cd ~/repo/org
    INITCOMMIT=$(git rev-list --parents HEAD | egrep "^[a-f0-9]{40}$")
    git format-patch -1 -o /tmp/mergepatchs ${INITCOMMIT}

    cd ~/repo/dest
    git am /tmp/mergepatchs/0001*.patch

  5. I’ve been researching a bit, and it’s easier to do it this way:
    git format-patch -o /tmp/mergepatchs –root

    Hope it helps!

  6. very nice and simple cosultion in comparision to others based on cloning the original repo, and then removing everything except the file in the cloned repo.
    But how to do, if the file was renamed ? Can we also recover the older commits of the file when it has another name ?

  7. Great instructions! Worked a treat! Thanks!

  8. I cannot make it work (meaning keep the history) when the file has be moved.
    My file hase 5 commits that modified it and the latest moved to to some other folder.
    When applying this technic to move the file from one repo to another, the patch is only containing the latest commit.
    Any idea on how to solve this issue ?

    • I finally got around the issue of renamed/moved files.
      Basically you to know the path of the file before it changed and add it to the list of files you create the patch on.
      something like
      git log –pretty=email –patch-with-stat –reverse –full-index –binary — new_file_path old_file_path > /tmp/new_file_path_history.patch

  9. easy, simple & most importantly working solution :-)

Reply to Anna Nguyen ¬
Cancel reply


*


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Trackbacks and Pingbacks: