5

I have this patch file, it contains a bunch of modifications that I'd like to apply to a git branch. But I don't want to make one unique commit with all those modifications, instead I'd like to split it into 2 or 3 commits.

I know I can achieve this by first applying the patch, then doing an interactive add (hunk by hunk), like so:

git apply mypatch
git add -p

I was just wondering if it's possible to do that in one git command. I found nothing in the manpages of git apply, nor in git add.

EDIT

I don't think this question should be considered as a duplicate of Syntax for Git aliases with multiple commands as that question (and its answer) does not need does not involve a parameter passed to the alias.

Community
  • 1
  • 1
arainone
  • 1,928
  • 17
  • 28
  • 1
    Why downvoted? Just curious – arainone Jan 22 '16 at 04:11
  • You could use an alias to combine them, or a function if you want to preserve git-like syntax with the new combined command. – 8bittree Jan 22 '16 at 19:29
  • @8bittree that seems a good solution. Would you care to provide me with such an alias (or function) in an answer? – arainone Jan 22 '16 at 20:06
  • Possible duplicate of [Syntax for Git aliases with multiple commands](http://stackoverflow.com/questions/18860696/syntax-for-git-aliases-with-multiple-commands) – Andrew C Jan 22 '16 at 20:55

3 Answers3

8

I'm replying to my own question, thanks to the comment of @8bittree.

There are at least 2 ways to do that:

  • using a shell function (see 8bittree's answer)
  • using a git alias. I prefer this solution as it only involves .gitconfig, no need to modify .bashrc, and git shell completion works for the new alias, it is shown alongside other standard git commands in the completion list

So this is what I ended to add to my global .gitconfig:

[alias]
    # interactive apply patch
    ipatch = "!f() { git apply $1; git add -p; }; f"

I then just have to do:

git ipatch mypatchfile
arainone
  • 1,928
  • 17
  • 28
2

As mentioned in my comment, you can get a similar effect with a function. After some more thought, I'm not sure if an alias would work, since you need to specify the patch file and possibly some options. Here's an example function you could add to your .bashrc, you may have to adjust if you use a shell other than Bash. I think it should work with Zsh, and maybe Ksh, but I have not tested it with those.

function git() {
    # Allows you to call `git ipatch patchfile`
    # Change ipatch to whatever you want the git command to be
    if [[ "$1" = ipatch ]]; then
        shift
        # Specify the full path to git, otherwise infinite recursion
        # Alternatively, name the function something else
        /usr/bin/git apply "$@"
        /usr/bin/git add -p
    else
        /usr/bin/git "$@"
    fi
}

If you want to add more custom git commands, it may be worth looking into a case statement, rather than a long chain of ifs.

8bittree
  • 1,769
  • 2
  • 18
  • 25
-1

You can use the unix "patch" command (separate from git). That way Git will not know anything about the 'patch' --- Git will just think you did regular editing. Output of "git show" and "git diff" is compatible with the unix "patch" command:

# assuming "my-git-repo" is clean...
cd my-git-repo
patch -p1 < my.patch
git status

At this point you can use "git add" / "git commit" to create the sequence of commits you want.

G. Sylvie Davies
  • 5,049
  • 3
  • 21
  • 30
  • In this context `git apply` does the same as unix `patch`, no more no less. The modified files are not staged for commit if that's what you thought. Furthermore the question is about finding a way to do an interactive `git apply`, in one command – arainone Jan 21 '16 at 20:14