
Git add -p: a powerful git feature - joshuacc
http://johnkary.net/git-add-p-the-most-powerful-git-feature-youre-not-using-yet/
======
daveungerer
Or you could just use a GUI app and save yourself a lot of time. SourceTree
(OS X only, free - <http://sourcetreeapp.com>) has changed the way I use git
since I started using it a few weeks ago.

The best thing is the discoverability - you don't need to know about the -p
flag, for instance, since it's handled by the UI. Same for many other useful
git commands that are hard to remember - they are often a simple option on a
right-click menu, or a checkbox when performing an operation.

~~~
johnkary
I never advocate GUIs as the primary means by which a developer works with
version control. Sure it might be OK for some things like browsing history
(GitX) but most GUIs often abstracts away much of the underlying complexity,
which is absolutely great if you're a designer without much command-line
experience, but absolutely a disservice to your in-depth knowledge as a
developer and the tools you rely on every day.

If you write code day in day out you SHOULD be comfortable on the command-
line. That's why I highlighted in the article that I need two tools to do my
development: an editor and version control. You use these tools every day--
EVERY day. There's no excuse for not knowing them intimately. They are the
foundation for doing your job.

GUIs also aren't always available across platforms, either. For the most part,
all the git CLI commands port from Mac, Linux and Windows (msysgit). Also,
have you ever tried using a GUI when SSH'd into a remote server in a pinch?
You can't. And you'll really wish you invested the time to learn those
underlying CLI commands.

~~~
rogerbinns
Do remember that half of all developers are below average/median for the
relevant group. (See also "perpetual intermediates".)

My experience has been in forcing developers to use guis to do commits. It
significantly improved their commits because they would browse over the
changeset, could commit only specific hunks, didn't accidentally include extra
gunk like test files, and generally made better messages.

It is certainly the case that the cli tools give experts the most power. But
that power doesn't need to be exercised by everyone, and not even by experts
on every occasion.

I would much rather my developer's heads are full of things relevant to the
problem being solved (which is what pays the bills) than intricacies of cli
tools.

~~~
Evbn
What does a graphical diff and GUI message editor with interactive changelist
management have to do with being "below median"? I came to write code, not
restart my workflow from scratch every time I want to slightly edit my change.

~~~
rogerbinns
Because everyone thinks of themselves as being above median, and a wiz at the
tools. They know all the flags, workflows etc memorized and think everyone
should be like them.

Whilst in the real world the other half do things like 'git commit -a' to make
commits which likely picks up unwanted gunk. A gui does not require memorizing
flags and makes everything plain.

------
dguaraglia
Or just use gitx (or git-cola on Linux, or git gui if there's nothing better)
and get a much better visual reference and easy of use. Not everything needs
to be done from the command line.

~~~
shaggyfrog
At least for OS X, SourceTree is way better than any flavour of gitx. It
provides a very nice interface for `git add -p`; I use it several times daily
to craft tidy commits.

~~~
lloeki
"gitx (l)" is much nicer and more complete than the old unmaintained gitx, but
it has a number of bugs and casually, awful memory leaks.

------
pielud
I don't ever use git -p directly, but I use magit
(<https://github.com/magit/magit>) for emacs, which makes staging changes this
way very easy.

~~~
div
Lately I find myself launching an emacs session just so I can use magit for
projects I build in XCode.

It makes crafting commits a joy.

------
owenjones
I Always use -p.

I can't count the number of times I've caught stuff that wasn't supposed to be
committed.

Also, site isn't loading for me so maybe this is discussed, but I also like
using it to not commit logging / debugging statements without removing or
stashing them.

------
squidsoup
For anyone using Mercurial, the hgrecord extension distributed with hg gives
you the same feature - <http://mercurial.selenic.com/wiki/RecordExtension>

I can't remember the last time I used a naked commit; record has become part
of my core workflow.

------
v33ra
"git add -i" is my favorite command to start the interactive mode to add
multiple files to staging at once.

------
pavel_lishin
John Kary's page is down, but he created two screencasts, which are the meat
of his post:

[http://www.youtube.com/watch?v=Wl0NfWYrvlY&feature=plcp](http://www.youtube.com/watch?v=Wl0NfWYrvlY&feature=plcp)

[http://www.youtube.com/watch?v=1tqMjJeyKpw&feature=plcp](http://www.youtube.com/watch?v=1tqMjJeyKpw&feature=plcp)

~~~
johnkary
Sorry everyone, thought we had Varnish setup. I'll do my best to get it back
up. My screencasts above are what I'm mostly linking to.

~~~
bencevans
There's a cache of the article here:
<http://hncache.bensbit.co.uk/4744405?textonly=1>

------
AlexBlom
Link is down. Cached page at:
[http://webcache.googleusercontent.com/search?q=cache:ybdWn7-...](http://webcache.googleusercontent.com/search?q=cache:ybdWn7-Xy9wJ:johnkary.net/git-
add-p-the-most-powerful-git-feature-youre-not-using-
yet/+&cd=1&hl=en&ct=clnk&gl=ca)

~~~
pooriaazimi
Every time I mention this on HN, at least 15 people upvote it - which means
they didn't know about it. So I feel obliged to repeat it again and again _(as
I usually use this method a few times a week and it's tremendously useful for
me)_ :

If you want to get Google's cached version of a webpage, just type

    
    
        cache:[url]
        e.g.: cache:http://johnkary.net/git-add-p-the-most-powerful-git-feature-youre-not-using-yet/
    

in the search bar and press return.

EDIT: 14 already, after an hour!

------
ptgloden
There's also 'git reset -p' to interactively unstage changes

~~~
panic
And _git checkout -p_ to interactively bring over parts of another commit (or
interactively revert uncommitted changes, if you're checking out HEAD).

------
__david__
Git's "add -p" ui is great. If you're stuck on another VCS you might want to
check out <http://porkrind.org/commit-patch/> which, through the "commit-
partial" command, lets you review and edit your patch before committing. It
works with many of the open source VCSes out there.

I tend to use it even for git just so I have a consistent interface no matter
what project I'm working on.

------
dpatrick86
Yeah, this is a great tip. It's great for a final review prior to actual
commit. Often, I'll build my commit message based on my walkthrough at that
point. Additionally, you get cleaner diffs because you can skip over goofy
stuff like whitespace changes (which you then can destroy after the commit by
a quick git checkout HEAD myfilewithwhitespacechangesinit)

------
philfreo
But I am using it!

~~~
tesmar2
But I am usin git?

------
minhajuddin
I do this but with git gui, it's much easier this way:
<http://i.imgur.com/3Mrwr.png>

------
mdonahoe
Site wont load for me.

I'm a big fan of "git gui". You can commit individual lines.

~~~
morsch
Here's another article discussing git add -p:
[http://blog.tplus1.com/index.php/2008/10/31/break-up-
changes...](http://blog.tplus1.com/index.php/2008/10/31/break-up-changes-into-
different-commits-with-git-add-p/)

Nice. Too bad I'm on svn. Though I suppose you'd want to be really careful
about not creating a commit that's broken, e.g. by overlooking a declaration.
Can you easily check whether currently staged changes still compile and/or
pass a test?

~~~
cdavid
yes, using the -k option of git stash allow you to 'put away' the changes
which are not in the index.

The argument of creating a broken commit is natural, but not very relevant
IMO: after all, with svn and co, the risk of forgetting to commit a new file
is pretty strong as well. If you care very much about having non-broken
commit, the only reliable solution is a gateway that merge commits only after
they pass a test suite.

------
pepr
Agreed. It's a triviality but git add -p is one of the main reasons my commits
in Git are cleaner than in SVN. It's also one of the advantages I cite when
advocating for Git.

------
martian
If you haven't tried it, I highly recommend taking a look at Stacked Git
(stg). It adds a beautiful layer on top of git that helps you manage a "stack"
of commits. Useful when you're working on a large change and want to think
about smaller commits.

Combined with `git add -p`, stg is easily the most useful git tool in my
toolbox.

------
mercurial
It's an absolutely fantastic (though dangerous) command. It's also a good
illustration of how git doesn't commit anything you don't want to see
committed (eg, "git commit" doesn't do anything if you haven't done "git add"
before, letting you prepare your commits more carefully than with other VCSs).

~~~
nas
You really need to test the version of the code you are going to commit. See
the comment about using "git stash" elsewhere in this thread.

~~~
DigitalJack
You need to test the version of the code you are going to publish, and unless
you are publishing every time you commit, you don't need to test each commit.

I use git add -p whenever I've made too many changes between commits. I like
for my commits to be of a single topic if possible.

If I use git add -p to break up a commit into 10 separate chunks, and find out
something is broken, it's not hard to find the commit that caused the issue
(if the commits are topical and not mixed).

------
tebeka
So you end up committing untested code? (since you did test the whole change,
not just part of it).

Sounds like a bad idea to me.

~~~
tjdetwiler
I usually do something like:

    
    
      git add -p
      git commit
      git stash
      <run tests>
    

If it fails then I can stash pop and commit -p --amend and try again.

~~~
_ikke_
With stash -k you can test without committing first. Although git is very
flexible regarding this, I prefer to at least test the code before committing
it.

------
erso
There's also git add -e, which I find to be more powerful as it gives you the
ability to choose the context of the changeset you're going to be staging by
glob.

I wrote a blog post about it here:
[http://pivotallabs.com/users/khicks/blog/articles/2116-git-a...](http://pivotallabs.com/users/khicks/blog/articles/2116-git-
add-e)

There's also git reset -p, which is also in the same realm as git add -e as
far as how powerful/advanced it is, though perhaps more difficult to
comprehend. I wrote a blog post on that one, too:
[http://pivotallabs.com/users/khicks/blog/articles/2114-git-r...](http://pivotallabs.com/users/khicks/blog/articles/2114-git-
reset-p)

------
jwr
You mean there are people who do NOT always use -p with add?

I guess you learn something new every day. I thought this was the only way
people use git and I was actually surprised to find out it wasn't made the
default.

------
cpeterso
When preparing a series of commits in a branch, what is the recommended method
for editing non-HEAD commits? I know how to _git commit --amend_ the HEAD
commit, but how would one modify an earlier commit and rebase/replay the
subsequent commits? _git checkout_ the earlier commit and create a new branch
from there?

In Mercurial, I would use an hg patch queue to _hg qpop_ , _qrefresh_ , then
_qpush_.

~~~
emillon
"git rebase -i" is what is commonly used instead of hg patch queues. You pass
it the name of the last unchanged commit, and it opens an editor where you
define what operations to do on it : fold commits together (fixup, like
qfold), stop for editing a commit, reorder them, change their description,
etc.

~~~
cpeterso
Thanks for the tip!

~~~
emillon
You're welcome !

------
macrael
I still feel like detailed commit messages and fine grained commits are just
too much busy work. I think that there must be a better, more automatic way.
I'd love to start with a system that just let you easily drag back and forth
history. I feel like the future may well still be built on top of git, but I
don't think that we need to be so meticulous with our code.

~~~
chrisfarms
I'm going to guess that you mainly use version control for your own projects
or in a small team of 2.

While the idea of a "Time Machine" style history is probably quite desirable
when working on your own, it's totally useless for practice of checking in
self contained "features", having them reviewed and potentially rolling them
back even after many other "features" have been added that you want to keep.

------
jimktrains2
I alias icommit="!git add -p && git commit -e -v" since i normally do the two
together.

~~~
kzrdude
commit has gained a `-p` flag "recently".

~~~
jimktrains2
I may have to update my alias then

------
splicer
One thing I don't like about it is that you often can't keep splitting chunks
down to the line level. I usually end up having to type 'e' to edit the patch
manually.

~~~
Cthulhu_
Yes, my main grievance with git add -p as well; someone fix this.

------
rnadna
It might be my eyes, but the video is too blurry to be of much use. A couple
of paragraphs would have been preferable.

------
rjzzleep
tig and git add -p are my standard way of using it. Sometimes from within
vim(yeah you can use fugitive, but it has its' own purpose.

beats any gui imho, although tig is technically a gui.

for those that don't know it, compile: <http://jonas.nitro.dk/tig/>

and type 'S'

------
drivebyacct2
OT: I'd love an interactive "Learn Git" webpage where you could learn to use
Git with demo scenarios. Something like "Try Ruby" but for git.

~~~
scrrr
All you need to do is type "apt-get install git-core" or "brew install git"
and you can try 95% of git out locally. Get a free bitbucket or github account
and you can do most of the rest. :)

OK, perhaps you are on Windows, then i am not sure if it's that simple.

~~~
rhizome
Step 2: write some code that exercises all git features

~~~
drivebyacct2
That was more what I was looking for.

"Oh, you're friend was 20 commits behind and did [some stupid] shit that wiped
out all commits and GUI tools aren't helping? Here's how to attack it..."
which is where my Git knowledge falls apart very quickly.

Regular commiting/pushing/remotes etc are all okay to me, except the bad
habits of using "sync" as a commit message when I move from my desktop to my
laptop and I don't have wip branch.

