Hacker News new | past | comments | ask | show | jobs | submit login
Git add -p (johnkary.net)
136 points by robin_reala on Jan 20, 2014 | hide | past | favorite | 86 comments

I'm using SourceTree [1] as my main Git UI when I'm not in the terminal, and it makes it very easy to stage only parts of a changed file. Just as the author describes, this feature really improves the quality of the commits. It also makes it easy to remove parts of the changes in a file that were only there for debugging purposes - prior to the commit without having to go back to the editor.

It is a wonderful feature, and the fantastic thing about the SourceTree UI is that it shows it by default making it really easy for everybody who uses the app to only commit the actual, relevant changes.

[1] http://www.sourcetreeapp.com/

I love how the author in a comment never advocates GUI tools because they "often abstracts away much of the underlying complexity".

WRONG. The expose the underlying complexity in a visual way much easier to interpret for the brain.

The argument of interoperability is valid, but please stop bashing UI tools just becuase "If you write code day in day out you SHOULD be comfortable on the command-line". UI tools exist for a reason.

Honestly, I hate most GUI tools myself. They're often clunky and poorly designed for my tastes. (Even if there does exist a good visualization, that doesn't mean it has been discovered.)

But in this case, I agree with you. The `git gui` command is great for committing changes in patch mode visually. I use it exclusively over `git add -p`. (And it comes bundled with `git`!)

Though I've since stopped using it as I've permanently left OSX for the hallowed and greener fields of desktop Linux (2010 17" Macbook Pro + dual SSDs w/ZFS + Gentoo), initially I found SourceTree indispensable.

Not only was the software well considered and stable, presenting the complexities of multiple RCS/VCS in an improved yet concise visual format, but the author was very responsive to feature requests.

I asked for the custom external functions (hooks) to be definable so that I could use it as a sort of IDE for launching VM-based tests of multiplatform codebases, or more generally so that anyone could launch anything against any revision of any branch. The feature was completed impressively quickly.

The ease of cherry-picking is brilliant, as mentioned by others.

SourceTree is truly powerful software that I would still be using now if there was a Linux port. God only knows the number of redundant git pulls I have typed! The biggest current limitations of SourceTree IMHO are platform specificity and overall gooey-centrism... some features like the aforementioned hooks could probably be usefully accessed from the terminal, and I was unaware at last use of a simple methodology for achieving this.

Same for git-cola [1]. It's a simple GUI just for staging/committing changes, nothing else, so it's useful in combination with the cli.

[1] http://git-cola.github.io/

If you use emacs, magit apparently also has this functionality (I haven't gotten magit to work yet). I personally use http://porkrind.org/commit-patch/ via its Emacs integration, which has the benefit of working for VCSes other than git (though I personally find that becoming more and more rare as time goes by). Commit patch also has the command line tool "commit-partial" in case you don't use Emacs.

Disclaimer: A friend and I wrote commit-patch.

Windows or Mac only, pass.

Git command line and Linux. The dream setup for masochists.

This is not needlessly inflammatory how? What does this add to the discussion?

You're probably right, but git just drives me insane. And so does the "no true Scotsman" approach to development.

Gitg for Linux also exposes this functionality in an easy to use way.

I use mostly the terminal, but when doing more advanced stuff like interactive adding, rebasings or cherry picking, SourceTree is my main tool.

I learned most of my git-fu from Sourcetree. It exposes a lot of the little-used git functionality.

Using source tree is a lot easier than git -p . I really like it.

The most powerful git feature John Kary just learned about. These linkbait headlines drive me crazy.

I, too, see stories on HN that are passing on information that I was already aware of. Instead of commenting on their obviousness, though, I just move on to the next story and let those who did not previously know enjoy their new found knowledge. I don't presume myself their better because I happened to be aware of it first.

Also, relevant XKCD:


I think the complaint is about the presumptuousness of the title of the post, not so much the obviousness of the content.

This title isn't even really link bait. It tells you the feature in thw title. If you know what the "p" flag does, no need to click on the link to find out. For those that don't know of the feature, it is enticing enough to get them to check it out

Im mostly disturbed by the "most powerful" part because this is subjective to project and how you work. It's not a very common case for me to commit parts of changes in a file because in most of my cases all changes I do to a file belong to the same commit since I work with feature branches. However when I do need this it's indeed powerful but judging by the enthusiasm of the post and title it just smells like the endorphin release of new feature discovering.

Even with topic branches, I find staging with -p to be a nice chance to review the diff piece by piece. Helps me build good commit messages, and makes it easy to split changes in to a set of commits if I feel thats necessary.

It is fairly an honest title. The guy talk only about that feature, use original content, talk about something available for free which he most likely does not have an immediate interest.

There is a little bit of exaggeration in the title to attract people. That's how you drive traffic to your site. And let's be honest, if the guy was driving traffic that way to the startup he founded, people would have much recommendation about much less honest strategies.

Or he could go with the much friendlier and less elitist: "feature you might not be aware of", "feature you might not be using yet".

It correctly presumes that those who don't know about this feature will find it useful. That's about it.

Would be nice to have a "hide this story" feature for such an occasion. Would also help for those instances where the community's interest in a topic exceeds your own.

This Chrome extension does pretty much what you want: https://chrome.google.com/webstore/detail/hacker-news-mark-a...

He came across as irritated. You came across as self-righteous.

Does the top comment in _every_ HN post have to be an argument, criticism, or complaint? If you don't find value in a given post, then just move on. I suspect a lot of folks had indeed never heard of this feature before now.

I found this introduction to git add -p to be extremely helpful. I've found myself in the position he describes (wanting to logically separate changes I've made to a file) many times, and I've usually handled it in a sub-optimal manner (making one commit that describes multiple changes).

The 'problem' is that this tip has been posted a lot on HN/Reddit. It becomes annoying for some people to keep reading about a "git feature you're not using yet". That said, the feature isn't well-known for everyone and it is very useful, so you can only expect negative as well as positive comments.

I've been a HN user for 701 days (as of today). This is the first time I've seen this topic here.. Sorry not all of us are on HN 24/7. This is new to me, and I appreciate it being posted, because guess what? I've never known of git add -p. Now I do. But wait, what if the person who posted this did indeed see something similar posted here last year and never posted it? Great, now I won't ever have known this great feature.

Like stated before. Don't like the content? Don't upvote it. Move on. The complaining in every thread about these things are more annoying than seeing the same thing posted again after a month or two.

The upvotes seem to validate the article's value, even if the topic has been posted in the past.

Because the title provides a statement without any evidence and is downright condescending?

Imagine a vast school, with all the kids intermingling, and one shouts up and says "My God I understand algebra!". This is a signal for the kids who are struggling with algebra to head in their direction and ask questions or copy the homework answers. Its also a good signal for kids who are working on groking calculus that he is not to be listened to.

To avoid this in schools we sit kids in age-related classes, of small size. But the world is a big school and there is no central authority who knows what we should learn and when.

We just need better filters to block out the noise of algebra-learning kids while we work on infinite series. Those filters might be news-style forums, at least until there are too many kids at different stages on here. Then we have to work on our own filters.

And listen for the kid who shouts "My god, I built a filter to ignore calculus learning kids!"

Edit: OK, Ok there is a difference between link-bait headlines and pre-known content. But the kid has to shout something.

I really hate these presuming "you don't know about" (a dozens of other variations) titles. This by itself makes me not want to read the article at all.

And I didn't use or know about the feature.

Author of the post here.

I obviously didn't just learn about patch mode... git has many powerful features, but I feel this is the most powerful of those that many git users don't know about yet that will make the biggest positive impact in their daily git use. Not that patch mode is the most powerful feature git has.

Do you know what drives me crazy? It's little men with a desire to feel superior who complain about inconsequential titles in an attempt to come across as intellectuals.

Good thing I am not a little man.

It'd be nice if people stopped complaining about articles being old news. The guy posted this in 2012, and said he learned it a year ago (2011).

If you already know the feature, move on to the next article. Other people don't know about this feature and upvoted it.

Exactly. Been using -p for a long time.

I love -p, but it still falls short of darcs interactive commit (which it is definitely inspired by).

darcs interactive commit allows you:

- to add files in the same process (in two steps: intent-to-add and then the file itself) - revert of hunks, file additions, etc.

Yes, you can do both through separate steps (git checkout -p for example), but darcs interactive was a quick way of incrementally building full patches in one workflow.

Is "git add -i" you are looking for?

No, because that has me navigating a menu.

And this is how pretty every command in darks works. So it really encourages you to commit small and independent patches. And after darks will easily do its magic.

Want to revert some one week-old change?

  darks rollback -p "That change name"
As easy as it gets

How is this different from git revert? Also, can I assume you mean darcs?

I've been using this for quite some time now, but only because GitX[1] has nice GUI support for this. (I'm too lazy to learn using this with git's CLI.)

[1]: http://rowanj.github.io/gitx/

The GitHub App for Mac[1] and Windows[2] as well as msysgit[3] (and probably others) have this feature as well. I always resort to these GUIs when only commiting parts of a file, because it's a very visual process and I believe a GUI is the right tool in this case.

[1] http://mac.github.com/

[2] http://windows.github.com/

[3] http://msysgit.github.io/

The standard git gui includes this, too.

I bet these are the features you're not using yet:

    git checkout -p
for discarding hunks from the worktree, and

    git reset HEAD -p
for unstaging hunks from the index.

Ah, the 'git checkout -p' is great. I always did 'git stash -p; git stash drop' for that. Putting this under 'checkout' is completely non-obvious.

Don't be so presumptuous! I've been using it for years.

And it's been suggested in almost every git talk/slides I've seen. But I'll admit it's so easy to overlook ..

The `-p` flag in general is very useful.

With `git add`, sure it allows you to stage part of a file. That not all, when you're in edit mode (pressed "e" upon the prompt) you just edit a patch. So you can actually put in your patch lines that are not in the source file. This can be very convenient e.g. if the 2 sets of change you want to commit separately are entangled. For example I used it yesterday to correct the level of indentation.

With `git stash show`, instead of having a short description of files changed in the stash, you get the patch itself.


Git man pages are well-written, and I always enjoy reading it. Most of the time I have one question but end up wiser (at least git-wise).

There's also a ncurses-based interface for git called tig[1]. I find it a bit easier to stage chunks/lines than git add -p as it's interactive. When I'm not on a command line, gitx-dev for OSX [2] also makes it very easy too.

[1] http://jonas.nitro.dk/tig/ [2] http://rowanj.github.io/gitx/

+1 for tig. I don't use it for staging and committing (I prefer to do all that using normal git) but it's ridiculously useful for quickly checking the git history, blames etc.

Is it me or does it seem like a lot of people seem to avoid using GUI's for git ? I mean git-cola, gitk, gitx, sourcetree etc are all great ways to manage your git repos and don't need complicated command line operations and make your job much faster/easier.

Well, I've got to be able to use git on Windows, Mac, and Linux, the last two possibly over SSH. Is there a GUI that would work well in all those environments? Someone just mentioned tig, which might be able to do the job, but I haven't tested it out yet.

You could always SSH +x into your server and run a GUI client that way.

Who says people don't use it? I use it because command line is kind of non-customized.

But being close to your CLI is never bad. After all, the tool might comprehend git badly. Git CLI rarely makes mistakes about Git.

I am comfortable with the Git command line and SSH into my development environment.

It's pretty useful, but it's also fairly easy to end up with an untested commit that doesn't really compile.

Fortunately git also makes it fairly easy to test only those changes that you've staged:

    $ git stash --keep-index
    $ <compile/run tests>
    $ git commit
    $ git stash pop

You might want to add this option:

  -u / --include-untracked
You're not testing only the index if you have untracked files lying around (which could possibly affect things). (Presumably you don't need to use --all because you're only ignoring files that don't affect things :P).

This feature is the reason I can't completely switch to command-line git from Sourcetree — it's much more convenient to quickly glance along code changes in multiple files and decide what to commit with a mouse.

For Mercurial, there's this "extension": http://mercurial.selenic.com/wiki/RecordExtension

"Extension" in quotes, because it comes with the Hg installation -- it's just one of those advanced things disabled by default.

I love mercurial, but you don't get quite the benefit of `git add -p`, because mercurial has no staging area. If you quit out of `git add -p`, you still get the benefit of having whatever you added staged. In contrast, if you quit `hg record` (because you wanted to change something before committing), you have to re-record all the changes you wanted.

if you use mercurial's mq extension you get the equivalent of a staging area if you really want one[1]. There is qcrecord to get git add -p functionality with mq.

Personally, I have stopped using queues and I use rebase and histedit extensively now. I see no need for patch queues or a staging area when you can edit and rearrange commits easily.

1. http://stevelosh.com/blog/2010/08/a-git-users-guide-to-mercu...

And an improved (real) extension: http://mercurial.selenic.com/wiki/CrecordExtension

Check out `git add -e` (http://pivotallabs.com/git-add-e/). Like `git add -p` on steroids. That said, both have their place depending on what you're trying to do.

Why are people so upset by the title? Is it a cheesy buzzfeed style bait? Yes, but why should I be offended by a random person on the internet insinuating I don't know about some random thing?

hmm. i've used git pretty regularly since 2010, after coming from svn. the more i use it the more it reminds me of being the administrator of a website -- sure, i _could_ have a password recovery form, but it's much easier for me to use this python script i've written that just edits a user's row in the logins table... that is, i've found git to be incredibly powerful, but in the process i've forgotten the safe way to do everything.

I use it already. Sometimes. But every time I use it, I think I do something wrong. Why I use it? Because my changes are more as one commit, because I mess another changes not related to my actually unit of work.

But if I didn't has git add -p, in svn for example, I create a patch and revert not related changes, commit, apply patch again. git add -p is just convient/useful shortcut and not mega-power-answer to all problem nor sources of problems.

For the vim users the fugitive plugin by tpope provides a nice way to do this using vim's vimdiff. It is a delight to use.

Here is a video of vimcasts tutorial. http://vimcasts.org/episodes/fugitive-vim-working-with-the-g...

I too discovered git add -p some time ago, and it has been very handy! However, a few days ago, I decided to finally give magit (an emacs extension) a go, and it really beats everything else I've tried out of the water.

In case you didn't already know, magit exposes `add -p` functionality in a very emacs-y way: it leverages the region concept by making it so that if you select the part of a diff you want to stage in your magit-status buffer and then press s it will only stage that region.

Didn't know about this. Glad you shared it. Thanks John.

FYI `git reset -p` works the same way. Sometimes, depending on your work and workflow it can be easier to add everything and then just exclude a few of the changes.

And `git checkout -p` too.

And `git log -p` is great for reviewing recent changes by your co-workers too!

For vim users, vim-gitgutter lets you stage/revert individual hunks. I find it much more useful than I thought I would (even being the plugin's author).

I always used 'git add -i' for this. That involved long steps before adding hunks. But this is so shortcut method. Thanks for sharing :)

Oi I've been using it for years; I feel insulted by your insinuation! (exaggerated sarcasm)

And if you use git commit -p it combines git add -p and git commit in one command.

Why would one use "git add -p" instead of "git add -i"?

I am already using it...everyday. Thanks for your assumption though!

git commit -p: The most powerful git feature you're not using yet

Oh come on. Teeny-weeny flag to a Git command ends up on the front page of HN. Amazing.

Great video.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact