简体   繁体   中英

Git merge file content outside of a repo (--no-index)

The git diff command (with the --no-index flag) works incredibly well to diff two files, irrespective of whether or not these two files are contained in a Git repo or not.

Example

$ git diff --no-index -- filea fileb
// shows diff between filea and fileb

Question

Is it also possible to use Git to selectively "merge" (ie git add ) content from one file to another if they are not part of a Git repo? Basically like a git add -p but not from the working directory to the index, but from fileb to filea .

I feel like all the basic building blocks (plumbing commands) should be available. Possibly something involving format-patch and/or apply ?

$ <command> filea fileb
// wanted: interactively choose patches/hunks from fileb and apply them to filea

git diff --no-index is pretty much just an ordinary diff , if you want to apply change hunks across arbitrary files, use an ordinary merge tool like vimdiff -- which is even harder to distinguish from vimdiff used as a Git mergetool because it's the same exact thing.

git add is for adding content to the repo, you're not working on two paths from the work tree, you're working on a single path from the work tree and whatever content is indexed at that path. In particular, you don't get the option to have two different names.

But Git itself finds its work tree (and repo, and objects, and index…) only if you don't explicitly tell it where they are. If you've got a snapshot of filea somewhere, say at /path/to/filea , you can

git --work-tree /path/to add -p filea`

and git will obligingly do a patch-add from the filea at that path to the filea content registered in the index.

The git add -p command is—or at least was 1 —a big Perl script. To view it, find the "core" directory:

git --exec-path

which will print something like /usr/lib/git-core or /usr/local/libexec/git-core . This is where various Git internal binaries and scripts live.

In whatever directory gets printed out, look for git-add--interactive . This is, or was, the git add -p code.

This Perl program runs the Git diff and apply commands, and should be relatively easy to modify to make it do what you would like done. Note that this is used for all of git add -p , git reset -p , and git checkout -p , which is why it's nearly 2000 lines long.


The Git project folks are in the middle of rewriting all of this to make it impossible for you to modify. :-) Er, that is, to make it written in C to go fast—you'll still have the source, and can still modify it all you like, but as a C program, it will be much harder to work on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM