Commit only part of a file in Git
You can use
git add --interactive or
git add -p <file>, and then
git commit (not
git commit -a); see Interactive mode in git-add manpage, or simply follow instructions.
Modern Git has also
git commit --interactive (and
git commit --patch, which is shortcut to patch option in interactive commit).
If you prefer doing it from GUI, you can use git-gui. You can simply mark chunks which you want to have included in commit. I personally find it easier than using
git add -i. Other git GUIs, like QGit or GitX, might also have this functionality as well.
When I make changes to a file in Git, how can I commit only some of the changes?
For example, how could I commit only 15 lines out of 30 lines that have been changed in a file?
When I have a lot of changes, and will end up creating a few commits from the changes, then I want to save my starting point temporarily before staging things.
$ git stash -u Saved working directory and index state WIP on master: 47a1413 ... $ git checkout -p stash ... step through patch hunks $ git commit -m "message for 1st commit" $ git checkout -p stash ... step through patch hunks $ git commit -m "message for 2nd commit" $ git stash pop
Whymarrh's answer is what I usually do, except sometimes there are lots of changes and I can tell I might make a mistake while staging things, and I want a committed state I can fall back on for a second pass.
vim-gitgutter plugin can stage hunks without leaving vim editor using
Beside this, it provides other cool features like a diff sign column as in some modern IDEs
If only part of hunk should be staged vim-fugitive
allows visual range selection then
:'<,'>diffget to stage/revert individual line changes.
Intellij IDEA (and I guess all other products of the series) has built in support for partial commits since v2018.1
git-cola is a great GUI and also has this feature built-in. Just select the lines to stage and press S. If no selection is made, the complete hunk is staged.
I believe that
git add -e myfile is the easiest way (my preference at least) since it simply opens a text editor and lets you choose which line you want to stage and which line you don't.
Regarding editing commands:
Added content is represented by lines beginning with "+". You can prevent staging any addition lines by deleting them.
Removed content is represented by lines beginning with "-". You can prevent staging their removal by converting the "-" to a " " (space).
Modified content is represented by "-" lines (removing the old content) followed by "+" lines (adding the replacement content). You can prevent staging the modification by converting "-" lines to " ", and removing "+" lines. Beware that modifying only half of the pair is likely to introduce confusing changes to the index.
Every details about
git add are available on
git --help add
I would strongly recommend using SourceTree from Atlassian. (It's free.) It makes this trivial. You can stage individual hunks of code or individual lines of code quickly and easily.
Much like jdsumsion's answer you can also stash your current work but then use a difftool like meld to pull selected changes from the stash. That way you can even edit the hunks manually very easy, which is a bit of a pain when in
git add -p:
$ git stash -u $ git difftool -d -t meld stash $ git commit -a -m "some message" $ git stash pop
Using the stash method gives you the opportunity to test, if your code still works, before you commit it.
git-meld-index -- quoting from the website:
git-meld-index runs meld -- or any other git difftool (kdiff3, diffuse, etc.) -- to allow you to interactively stage changes to the git index (also known as the git staging area).
This is similar to the functionality of git add -p, and git add --interactive. In some cases meld is easier / quicker to use than git add -p. That's because meld allows you, for example, to:
- see more context
- see intra-line diffs
- edit by hand and see 'live' diff updates (updated after every keypress)
- navigate to a change without saying 'n' to every change you want to skip
In a git repository, run:
You'll see meld (or your configured git difftool) pop up with:
LEFT: temporary directory contining files copied from your working tree
RIGHT: temporary directory with the contents of the index. This also includes files that are not yet in the index but are modified or untracked in the working copy -- in this case you'll see the file contents from HEAD.
Edit the index (right hand side) until happy. Remember to save when needed.
When you're done, close meld, and git-meld-index will update the index to match the contents of the temporary directory on the right hand side of meld that you just edited.