
My Git Habits - swah
http://blog.plover.com/prog/git-habits.html
======
Osiris
I'm fairly new to git. I've only been using it for about two months. It seems
like this is a lot of work with the end result only being that the commit log
is cleaner and perhaps makes cherry-picking a feature/fix a bit easier.

I can understand the need for this kind of cleanup when pushing a fix to an
open-source repository that needs pull requests to be self-contained, but for
an internal company repo, how important is it to keep the commit history this
clean?

If I have changes I'm not ready to commit and need to switch branches to work
on another issue, I find that doing a STASH is an easier way to go. I can just
stash my working copy changes, switch branches, then come back and apply the
stash and keep going and then make one final commit with just the final
changes I want to commit.

Other DVCS actually believe that being able to modify commit history is a bad
thing and lean toward immutable commit history (e.g., Veracity). Git makes it
pretty easy to modify commit history which is ok for local branches but can be
easily misunderstood to break your branch if you're trying to modify commits
that have already been pushed to a remote repo.

I like the idea of keeping the commit history clean but I'm not sure that it's
worth the effort that it takes to manage the process. In the end, only your
final good code is going to be merged into an integration or master branch
anyway.

~~~
gchpaco
Here are some of the situations I run into on a regular basis at my current
company, which is Perforce based, where I wish we were git based instead. This
would be as true in Subversion. They might be maybe less true in Mercurial or
Bzr, I'm not as familiar with those ones.

* I am hacking on some bit of code, so I set up a Perforce branch. While I'm at it I notice some ugliness and want to refactor it. I could make a new Perforce branch and put it there and then do some horrible merging apparatus but it's complicated and they live forever and it takes me out of the flow state, so I just make a commit. It is now very difficult to extract that commit from its context so that I could apply it independently.

* I make a mistake on a commit that is on a private Perforce branch, or maybe I did something out of order. The Perforce way is "you shouldn't have done that, then." and so my commit logs are full of "fix stupid typo" type commits that are basically just noise.

* I forget to add a file to Perforce and nothing tells me about it, ever, until we get to testing (or sometimes to production!) and Puppet won't run because it can't find some file <foo>. This is fixed with the 2012 betas and p4 status, but those require a server upgrade (because the p4 client is a thin wrapper around what the p4d server understands) and that isn't in the cards yet. This alone is enough to make me want to use git-p4 for everything.

* You can really tell that Perforce is built around a file system of RCS files sometimes. While it has atomic commits, many, many operations are based on individual file revisions (labelling, cherry picking, merging). This leads to the following:

* Cherry picking in Perforce is hard, because it's hard to get handle on the content of a changeset, as opposed to individual upticks in each of the files referenced. It can be done but it is a lot of effort, way more so than in git.

This is not the entirety of my complaints about Perforce, by any means, but
they're the most visible UI limitations compared to what I'm used to from git.

~~~
encoderer
Mercurial is more like Git than not. It differs in the way it stores revision
history (Git stores files, Mercurial stores deltas, basically).

And branching is Mercurial isn't nearly as neatly implemented as it is in Git.

But it would seem to address the issues you listed here. For example, you can
rollback a commit if you did the "stupid typo" mistake. And you have a lot of
power to "change history" and modify the DAG anyway you wish.

~~~
ezquerra
In my opinion branching _used_ to not be as neatly implemented as it is in
Git, but that is no longer the case.

A couple of versions ago a new feature was added into core mercurial, called
"bookmarks". Mercurial bookmarks are the same as Git branches.

So now you can use the "git style branches" (i.e. bookmarks) in mercurial, or
you can use the regular mercurial-style branches (which I personally prefer to
git's anyway). In addition you can use "anonymous" branches, which AFAIK do
not exist in git at all.

~~~
pozorvlak
Anonymous branches are AFAICT the same thing as detached heads. They're
discouraged in git, but they work fine.

------
mdehaan
Maybe it's just me, but using short lived topic/feature branches and squash
merges seems much easier than remembering all of these steps to "fix up" all
these things.

I think it becomes some what of a game to use all the more obscure corners of
git when a good 20-30% of it goes a long way.

Using less commands is more.

~~~
mcknz
I agree, but that also requires a discipline/foresight not all of us have. :)
I try to keep my feature branches as atomic as possible, but sometimes I get
ahead of myself and work on multiple things that really shouldn't be in the
same commit. I wouldn't use this model as my main workflow, but it's
definitely useful in certain scenarios.

~~~
gcb
if your code is 'live' and you plan ahead a few features: feature branches.

if you are running as fast as you can for the first releases, what i do is use
feature prefixes on the commits. And of course, a commit can have several
prefixes.

of course, if i have to cherry pick something, i still have to look at each
commit, but with prefixes it's easy. And i have the time i didn't spend
thinking ahead for something i don't even know i will need.

------
DavidWoof
This seems like a pretty terrible workflow to me, do others here actually work
like this?

I only use git-add -p when I've screwed up and didn't commit when I should
have, so I have to split the current commit into two. It seems to me that
rebase -i and merge --squash are better suited to re-writing history in the
way that's being done here. I'm especially distrustful of any workflow that
includes the line "I eyeball the diff".

But I'm no git guru. Is this a common way to work? Are there advantages over
the alternatives?

~~~
pja
It means you keep your original history around & build a new one which breaks
the code changes into functional chunks.

Rewriting your existing history with git rebase -i is fine until it goes
horribly wrong & you have to go groveling through the reflog to work out which
commits you need to rescue in order to retrieve your lost work.

~~~
DavidWoof
I don't see that. Keeping your original history around is a function of doing
cleanup on a separate branch. It has nothing to do with how that cleanup is
achieved.

Rewriting your existing history with git reset can also go horribly wrong,
which is why it's done on a separate branch here.

------
6ren
I think in part he's documenting modules. Because modules often crosscut the
primary hierarchy of files/classes/methods, it's awkward to document in the
source itself, and so usually isn't documented at all.

Git allows documentation across files; and because commits are naturally
associated with specific revisions, it can't get out of date.

{ Still, it does seem a lot of work, and it would be nice to document within
the source itself; and in a way that helps and is needed by the code (so it
can't get out of date). A bad example: specifically requiring/importing
another class before being able to use it. This documents dependencies, and
remains current or your code stops working (it would need to be an error to
require a class without using it). It is a "bad example" because it doesn't
_help_ you, just raises a barrier then "helps" you cross it, like a stand-over
man in an extortion racket.

What's needed is some immediate benefit (e.g. reduce code) to associating
files/classes/methods in a crosscutting "module". }

------
Feoh
I said this in a reply, but lest it get lost in the shuffle, here goes. I have
a __tremendous __amount of respect for mjd. His seminal articles on Perl,
particularly "Suffering with Buffering" and "Coping with Scoping" saved my
bacon more than once. However, I'm a release engineer, and this is an awful,
awful Git work flow. As others have noted, Git was designed so that you can
make wacky wild experimental changes off to the side in branches, and only
when you're happy, merge them back to your working branch and eventually into
master. This approach needlessly complicates things and seems incredibly error
prone, especially the bit about having to do house cleaning on the morass of
broken commits.

------
krupan
Wow. I've written about how powerful revision control tools become not just a
place to stash diffs, but a full-on code editing tool ([http://bryan-
murdock.blogspot.com/2010/09/mercurial-is-teh-a...](http://bryan-
murdock.blogspot.com/2010/09/mercurial-is-teh-awesome.html)), but this is very
impressive.

I think he mentions that he does test these new commits that he creates as he
goes about re-arranging history, but I think that should be emphasized more.
I'd rather have a messy looking commit that passes tests than some nice
looking commit that doesn't. bisect is powerful command that shouldn't be
broken.

------
helpbygrace
By the way, that article page is too hard to read comfortably. Shortened the
width of each paragraph and upsize the font will be really good for me to read
it.

tl;dr , I didn't read that page. :(

~~~
yogsototh
You might like this tool (I read the article using this):

[http://readable.tastefulwords.com/?setup&change&text...](http://readable.tastefulwords.com/?setup&change&text_font=Goergia%2C%20Palatino&text_font_monospace=Inconsolata&text_font_header=quote%28Times%20New%20Roman%29%2C%20Times%2C%20serif&text_size=20px&text_line_height=1.5&box_width=30em&color_text=%23657B83&color_background=%23FDF6E3&color_links=%23B58900&text_align=justified&base=web_readability&custom_css=pre%2C%20tt%2C%20code%20{%20%20%20%20background-
color%3A%20%23EEE8D5%3B%20%20%20%20color%3A%20%23586E75%3B%20}%20pre%20{%20padding%3A%201em%3B%20overflow%3A%20auto%3B})

------
Vitaly
I just use gitx when I'm on OS X or tig when I'm on a terminal for per chunk
or per line (gitx only) staging. git -p is too user unfriendly.

~~~
snprbob86
Once you get used to reading diffs in your terminal, git -p (and -i) turn out
to be very useful friendly. It's really easy to just slam y or n a bunch of
times, rather than click around a lot.

~~~
Vitaly
big just uses text diffs as well, only color coded which really adds to the
readability of it. I don't need guis for most of the things. The benefit of
GitX over tig or git -p is that it easily allows to stage a single line
instead of the whole chunk

------
brown9-2
_Often I'll be in the middle of something, with a dirty work tree, when it's
time to leave for the day. Then I'll just commit everything with the subject
WIP ("work-in-progress"). First thing the next morning I'll git-reset HEAD^
and continue where I left off._

Curious, what is the advantage of doing this? Why commit something locally
just to reset it out the next morning?

~~~
telemachos
He explains here:

> _Such commits rarely survive beyond the following morning, but if I didn't
> make them, I wouldn't be able to continue work from home if the mood took me
> to do that._

~~~
Davertron
I think the underlying assumption here is that he commits and pushes these
changes somewhere accessible from home and not taking it with him on his
laptop or something. Otherwise there really isn't a good reason for committing
it.

------
tomdeakin
git-add -p is new to me, but looks like something I'd wish I'd known about for
a long while. The number of times I end up copying changes (like a new
function) into some temp file while I commit is more than I'd care to admit.

~~~
pja
You can also git-add -i to go through the staging area & stage/unstage
individual patches.

~~~
jedbrown
Or use git citool or an emacs mode like egg or magit (other editors have
similar) that let you conveniently stage by hunk or line.

------
alpad
My first thought: crazy.

Especially the part with the printouts and highlighters.

Could this actually be effective?

------
swah
When you guys delete a feature/complex function that you wrote just to
discover you don't need it, do you guys mark it somehow to know something that
worked was removed in that commit?

------
dddima
Like 'git add -p' but much much better:

[http://porkrind.org/missives/commit-patch-managing-your-
mess...](http://porkrind.org/missives/commit-patch-managing-your-mess/)

------
b2spirit
Habits pronounced hubbits.

------
gerad
git commit -v is nice too

------
batista
The proliferation of "git tips", and "my git habits", "git best practices"
articles, make me think that Git is too complicated for its own good to need
all those.

(Maybe "need" is a bad choice of words: maybe it doesn't need those articles,
but it's too complicated if it gets to _have_ them. You don't get such
avalanche of advice for a simple, no BS, tool).

Now, the complicated part means it's flexible --in the rare cases you need it
to be. But it could probably use a facade that makes the common use cases more
intuitive (there are some half-baked attempts that I'm aware of).

Personally, I use mercurial.

~~~
eridius
The proliferation of "photoshop tips", "photoshop tutorials", etc, make me
think that Photoshop is too complicated for its own good to need all those.

</snark>

~~~
batista
Probably you meant to use the </misguided snark> tag.

The Photoshop Tips and Tutorials are about doing something new in a realm with
inherently _infinite possibilities_ , that is bitmap editing/drawing.

Managing source code shouldn't have "infinite possibilities" -- there are a
few common use cases, and several more uncommon.

If you have "infinite flexibility" in your source code management system, you
are doing it wrong, or at least inefficiently structured or streamlined, that
is, in the wrong end of the scale of 1 => you do everything by hand, 100 =>
the computer does all for you as you want it to.

Not all workflows can fit an one-size-fits-all team, sure.

But that doesn't mean that you should have to micromanage the workflow even in
the most common use cases.

I.e Git is more of a "source code management DIY kit" than a "source code
management tool".

~~~
eridius
Some people like micromanaging their workflow. Apparently Mark Dominus is one
of them. Other people don't like managing their workflow, and thus they end up
with just `git commit -a; git push` as the entirety of what they use. Just
because _some_ people micromanage their workflow doesn't mean everyone has to.

------
PaulAnunda
all i use:

    
    
      git add . && git status
    
      git diff --cached | mate
    
      git commit -am "this is what i did"
    
      git push
    

and when it hits the fan...

    
    
      git reset --hard

