The creation of git format-patch follows renames such as git log --follow

I am trying to transfer files from one local git repository to another local git repository for another project while saving history from the original repository. So far I have this, which works fine if the file has never been moved or renamed to the original repo:

# Executed from a directory in the target repository
( cd $SOURCE_REPOSITORY_DIRECTORY && git format-patch -B -M --stdout --root $SOURCE_FILENAME) | git am --committer-date-is-author-date

This happens because the directory structures of the two repositories are the same. If they were different, I would have to create patch files and correct the directory names using sedor something like that.

In any case, it all swells until I hit the file that was renamed. Despite the fact that I specify -B -M(and get the same results with -B -M -C --find-copies-harder), I do not get the fix until the move, although the file was cleared (similarity index 100%).

This is especially strange since it git log --followshows all the commits and git log --follow -pprovides all the differences. Except that he provides them in the reverse order, so I cannot feed them in git am.

Notice that the git log --follow -p filenamefollowing “patch” is displayed to display the rename:

diff --git a/old_dir_name/dir1/dir2/filename b/new_dir_name/dir0/dir1/dir2/filename
similarity index 100%
rename from old_dir_name/dir1/dir2/filename
rename to new_dir_name/dir0/dir1/dir2/filename

, git log git am, , , . git log --reverse --follow -p filename , .

, git format-patch, , / ? , git log -p , git am, ?

git 1.8.4.3.

+4
3

, .

  • log --follow, , // ( ).
  • , , log.
  • format-patch, , .

, - :

 git format-patch -B -M -o /tmp/patches --root -- old_dir_name/dir1/dir2/filename new_dir_name/dir0/dir1/dir2/filename

, . , , , , , .

....

+2

, , Bash, , .

script git-format-patch-follow, https://github.com/erikmd/git-scripts, OP: ( cd "$SOURCE_REPOSITORY_DIRECTORY" && git format-patch-follow -B -M --stdout --root --follow -- "$SOURCE_FILENAME" ) | git am --committer-date-is-author-date

: git format-patch-follow <options/revisions...> --follow -- <paths...>

, Bash script , @OldPro, , , , , CLI, script Git.

, , script PATH Git, script Git git format-patch-follow.

+2

. , . , --reverse --follow, :

[rename foo to bar]
$ git log --follow bar  # works
$ git log --follow --reverse -- foo # requires "--" because foo is not in HEAD

... . , , , .

tree-diff.c :

static void try_to_follow_renames(...)
{
        ...
        /* Remove the file creation entry from the diff queue, and remember it */
        choice = q->queue[0];
        q->nr = 0;

, diff_might_be_rename true:

static inline int diff_might_be_rename(void)
{
        return diff_queued_diff.nr == 1 &&
                !DIFF_FILE_VALID(diff_queued_diff.queue[0]->one);
}

...
int diff_tree_sha1(...)
{
        ...
        if (!*base && DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) {

, , "file bar , , foo, ", if , " foo, , bar, ", ... , .

, - , , diff ( format-patch log --reverse), diff_might_be_rename() try_to_follow_renames() .

, , , , .: -)

+1

All Articles