Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git one-liner for applying a patch interactively

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.

like image 472
arainone Avatar asked Jan 21 '16 19:01

arainone


2 Answers

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
like image 164
arainone Avatar answered Sep 25 '22 16:09

arainone


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.

like image 25
8bittree Avatar answered Sep 24 '22 16:09

8bittree