
Flight rules for Git - spenrose
https://github.com/k88hudson/git-flight-rules
======
smacktoward
It never ceases to amaze me that:

1\. Git, a software product with more footguns per square inch of user-exposed
surface than any I've ever encountered, ended up winning the distributed VCS
sweepstakes; and

2\. Even now, more than five years after it was clear to everyone that Git had
won, there is absolutely no momentum to go back and clean it up to _remove_
any of those footguns. All we get instead are increasingly shiny GUIs to hide
them under, and well-meaning blog posts advising you on which is the best kind
of tourniquet to apply when you trigger one of the aforementioned footguns.

Sigh.

~~~
finnthehuman
It’s basically a manifestation of programmer arrogance that they’re just too
damn smart to encounter a software learning curve again.

Ever sat through user training on microsoft office? How to use email? The
weird one-off enterprise apps that nobody else has ever heard of?

They’re unbearably tedious to users that can get by in a new tool with a 5
minute crash course, intuition and light googling.

Then git shows up and has the audacity to ask professionals to learn its
mental model.

Once you do the interface isn’t great, but not particularly esoteric. The
problem isn’t that users see dense-sounding things like “directed acyclic
graph of revisions”, it’s that they assume they can competently manipulate one
without knowing what that means.

I do think the interface could use cleanup, but can any ammount of cleanup
prevent needing to know the mental model of git?

~~~
masklinn
Bullshit. The "mental model" has never been the issue with git, it's always
been that the UI is garbage and a giant abstraction leak, requiring knowing
the implementation details of the commands and the storage model to work with
and step over footguns. Because rather than an actual, designed, considered
UI, the porcelain is crummy shortcuts on sets of operations on the underlying
storage (not mental) model.

Mercurial has the same "DAG of revisions" model as git, and works just fine,
because it has a good UI.

Darcs has a more unusual mental model than git, and works just fine, because
it has a good UI.

~~~
meuk
The biggest leaking abstraction of git IMO, are commits: they equate a set of
_changes_ with the state of the repo _after said changes_. So if there are
multiple commits, reverting a commit is ambiguous. Does it revert the state of
the repository to the state before the commit, or does it revert the changes
in the commit?

There are a couple more flaws. The commandline is not very consistent, and the
complete model is way too complicated IMHO. I can work with it now, but it
took me a long time to grasp all of the concepts that I need - without feeling
the need for distibuted version control. About that: It's kind of ironic that
git is hailed for being distributed, but everyone just uses github, a
centralized system.

~~~
cesarb
Just to be pedantic, a commit is actually "the state of the repo after said
changes" _plus_ "the commit(s) before said changes" (which allows one to
recover the "set of changes" by comparing the before/after states).

~~~
meuk
I don't think that's true. At least, not if you revert something - it reverts
only the changes introduced in that commit. (That there is confusion - or even
discussion possible - is exactly my point: the abstraction is leaky at worst,
and confusing at best).

Edit: You're right, but my point was that the revert command treats a commit
like a set of changes, not like the state of of a repo (since you can't revert
the state of a repo, but you can revert changes).

~~~
cesarb
See for yourself: do a "git cat-file commit HEAD" on any repository. The
"tree" line is the current state, the "parent" line(s) are the preceding
commit(s). That command shows everything git has recorded for any commit (you
can similarly use "git ls-tree <sha1>" to show everything git has recorded for
any tree, or "git cat-file blob <sha1>" to show the contents of a file from
the tree).

~~~
meuk
You're right from a technical perspective. What I meant that _as an
abstraction_ , it serves a double purpose (it represents both a node and an
edge in the DAG, and it depends on the command that you use which
interpretation is right).

If you checkout a commit, the commit represents the state of the repository.
If you revert a commit, the commit represents a set of changes.

------
noxToken
Everyone talks about how confusing Git is, and I think it's because they do'nt
understand what the commands do. Don't get me wrong: you can royally screw up
your repository with the wrong command, but 85% of your issues can be solved
with checkout, pull, add, commit, push, merge, reset, status, stash, branch.
When things get really heavy you may have to use rebase. And in spite of what
people say, there is a nifty log that's perfect for revisiting a snapshot of
your CLI's action: reflog.

When I first started using Git, I was told, "When you want to make you commits
public, use `git push -u origin <branch>` where branch the branch you're
pushing to." That advice is technically correct, but I had no idea what -u nor
origin was. I took 5 minutes to decipher the command. I walked away understand
that origin an alias for the remote server, and that -u associates a remote
branch with your local.

I don't think Git is the greatest thing ever. I do think there's a bit of a
learning curve. I also think that it's not as complicated as people make it
seem. This post is a great reference for how to do X in Git, but it's a
terrible source for beginners learning how to use Git. Cheat sheets are most
effective when you have a basic understanding of the material.

~~~
smacktoward
_> Everyone talks about how confusing Git is, and I think it's because they
do'nt understand what the commands do._

If nobody understands what the commands do, the problem is _with the
commands,_ not with the people.

~~~
dasil003
It's not this simple. Git's porcelain is very unintuitive, but the underlying
model is not. Once you understand the model, memorizing the commands is a
relatively minor annoyance. But even if you fixed the porcelain there is
essential complexity in understanding and utilizing the underlying model. To
further clarify would require simplifying the model or features exposed,
reducing the power of git as a tool.

There are those who say you should never rebase as a form of simplifying git,
but people who follow that workflow have much _much_ messier histories than
those who know how to rebase properly. A well-curated history of well-
explained atomic commits has _incredible_ value, far outstripping the cost of
maintenance on a long-lived project.

Git is a professional tool for software engineers, it has severe short-comings
for non-coders, but as a software engineer learning it well will magnify your
value.

~~~
smacktoward
If the Git developers have made an explicit decision that it's impossible to
simplify the interfaces without losing some important functionality, hey, it's
their software, that's their prerogative. But if that's the case, then people
who have trouble understanding the interface shouldn't be called dumb, or
chided for "not understanding the model," because it means _the model is going
to be too complicated for some people to understand._

Either Git is intended to be a tool anybody can pick up and use, in which case
it's shameful how thoroughly ignored widespread complaints about the UI have
been; or Git is intended to be a tool for a select priesthood of Enlightened
Masters, in which case it shouldn't be promoted to the unwashed masses. You
can't really have it both ways.

 _> Git is a professional tool for software engineers_

Lots of tools for professionals of all kinds take the time to protect their
users from inadvertently harming themselves through misuse. Cars for
commercial drivers aren't sold with a set of wheel chocks in place of brakes,
and if you argued that they should be because they're meant for _professional
drivers_ who _ought to know better_ than to walk away from their vehicle
without setting the chocks first, you'd earn yourself a lot of funny looks.

------
lixtra
I started version control with CVS. Just a bit better than copying.

I started distributed version control with monotone. That felt better but the
central db felt a bit unnatural.

A bit later came mercurial and I was really happy with it. It all made sense.
Easy interface and when you wanted to do something strange like rewrite
history, you had to use a plugin.

Then came git (rhymes to better know your sh*t). I'm not surrounded by the
smartest guys but most people I met only have a superficial understanding of
git and looking at these flight rules kind of confirms the complexity of git.

I strongly believe that 80% of the current users of git would be better off
with mercurial. But then everybody uses git for the remaining 20%.

~~~
pavel_lishin
Mercurial doesn't have branches, right? That drove me _bonkers_ when I was
doing a bit of contract work after having used git for awhile.

edit: They must have been using a different SCM; ignore me!

~~~
BerislavLopac
Not only that it has branches -- it has four different ways to branch.
[http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-
me...](http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/)

~~~
masklinn
Of note: Git has 3 of those:

* git has clones

* git has bookmarks, that's "normal" git branches

* git has anonymous branches, it's called "detached head" and is completely broken

* git _does not_ have named branches (that's the branch name being part of the commit's immutable metadata)

~~~
krupan
I've seen plenty of git users put "[JIRA-1234]" at the beginning of a string
of commit messages. That's basically poor-man's mercurial named branches.

~~~
chopin
Isn't that what a tag int Git is for?

~~~
BerislavLopac
A tag applies to an individual commit, and is unique (i.e. you can't have the
same tag on multiple commits); a named branch is applied to all commits in a
branch and persists after merging. In the example mentioned by @krupan, the
users tend to (and some team even require it) prefix each commit with the
ticket name or similar identifier.

------
Sir_Cmpwn
One of the reasons git is "hard" is because too many people read crap like
this, which rapidly gets outdated and often contains more bad advice than
good. Read the manual! It's not dry at all, and you'll learn a lot. Pick a
random git command and read its man page right now.

[https://git-scm.com/docs](https://git-scm.com/docs)

Read the git book, too. It's free and serves as a good introduction and helps
you learn which man pages you need to consult and when. You don't need to read
the whole thing, but the first 3 chapters are indispensible.

[https://git-scm.com/book/en/v2](https://git-scm.com/book/en/v2)

~~~
CleanShirt
Can you give some examples of how git has rapidly changed?

------
wgerard
A simpler guide, perhaps, made by an incredibly talented former co-worker of
mine: [https://ohshitgit.com/](https://ohshitgit.com/)

~~~
lprd
This looks great, thanks!

------
marcosscriven
Reminds me of the git man page generator joke site. [https://git-man-page-
generator.lokaltog.net/](https://git-man-page-generator.lokaltog.net/)

------
Klathmon
This only briefly touches on revert commits, and instead shows a lot of (in my
opinion) dangerous history-destroying commands.

Why aren't reverts more widely used? It seems a lot of devs I've worked with
don't understand them, and to me they seem so simple and are so much safer
than destroying/rewriting history.

~~~
t0mbstone
I will explain a common problem with revert commits:

1\. Developer writes some code in a branch.

2\. Developer merges code into master before the code was actually ready to be
deployed.

3\. Developer reverts the merge commit in master to roll back everything.

4\. Developer fixes the code in their branch.

5\. Developer merges their code into master.

6\. Their code doesn't show up in master, since it was already merged in and
the revert is part of the official history of the branch in master.

7\. Developer has to make a revert of the revert and then untangle the mess.

~~~
Klathmon
I can understand that, but I still would prefer that over the alternative of
changing history, losing context at why the revert happened (or that it
happened at all!), and having to dig through reflog and hope that the machine
that it was done on is available and hasn't dumped the code to be able to
recover the commit needed.

In your scenario, it's a puzzle to unfuck, but it's unfuckable after a bit of
work. In the alternative you run the risk of losing work, or blowing out
other's commits and causing work for multiple other team members.

I guess my point was that I feel "revert commits" should be treated as the
default, and the goto in most situations, and only using something like `git
reset HEAD^ --hard` when you really need to, or a revert won't do. I'll be
honest, I sometimes use a "reset and force push" when I've fucked up an ugly
merge, or I want to undo the last few commits at once, but it's the exception,
not the first tool I reach for.

------
dschuler
This is interesting - I like looking at corner cases of a tool to understand
it better.

For people having difficulty with git, I recommend going through the official
book [0] on a couple of topics with a toy repo and play with the tool a little
bit. Another alternative is to find a simple workflow, and stick with it until
you have time to explore git more.

Compared to other tools I've had to use in the past (AccuRev ughh), git is
fantastic. Just being able to see what files have been modified without
waiting for 10min+ or needing to be connected to a server changes your
workflow, but we've probably become accustomed to those benefits, but still
notice the arguably crusty command line.

[0] [https://git-scm.com/book/en/v2](https://git-scm.com/book/en/v2)

------
okket
FWIW here is a previous discussion from 4 years ago:
[https://news.ycombinator.com/item?id=8102624](https://news.ycombinator.com/item?id=8102624)
(29 comments)

------
pvinis
Any suggestions for quickly doing the following: When I clone a former repo on
GitHub, I want to also add the original repo I formed from, as the upstream
remote. This way I have the original repo which is mine and the upstream repo
which is the original. So far I've been doing this manually.

~~~
SpaceNugget
go to [https://github.com/github/hub](https://github.com/github/hub) install
hub and run: hub fork user/repo

------
jeffwass
Seeking advice from the git masters :

I joined a new small team several weeks ago. All of us are fairly new to git,
coming from cvs and svn backgrounds. We use Intellij as our primary IDE, and
bitbucket as our remote origin.

 _Do y’all recommend using the IntelliJ git front end GUI, or calling git from
the command line?_

I thought I had a grasp of git from some side projects on GitHub, but now that
it’s a key dev tool in our daily process, the more I learn about it and need
to extend beyond simple checkout/commit/push workflow, the deeper the rabbit
hole goes.

~~~
peheje
Learn the git cmd prompt first.

Use a text editor eg. Code to fix merges.

Git is powerful. And can have a hard learning curve, but don't have to. Learn
it in CMD.

I mostly use

status push pull commit -a add checkout checkout -b branch list merge

Gitk and git GUI usually comes with most installations and works for Mac
Windows Linux. Then any other UI is just sugar.

------
kureikain
IMO, by blindly follow these kind of cheatsheet, you will hard to get better
with Git.

I used to remember command in certain situation and have a hard time
understanding stuff like stash, rebase, cherry-pick, detach head etc...So
whenever come up I have to sit google the heck out of it.

Then one day I decide to sit down and just read Git properly. They are on:
[https://git-scm.com/](https://git-scm.com/)

Eventually I understand it better and now I know what I need to do in certain
situation.

------
spenrose
I also highly recommend Learn Git The Hard Way. Most developers who spend an
afternoon with it will come away with a firm understanding of git's core
abstractions.

Book:
[https://leanpub.com/learngitthehardway](https://leanpub.com/learngitthehardway)

------
xtracto
I was surprised there is no mention of git bisect... an incredibly useful
tool.

------
projectramo
Isn't the first rule, never talk about Flight rules?

------
anonuser123456
If git confuses

Read chapter 10 of pro git

Mourn enlightenment

------
Narew
that remember this so much [https://xkcd.com/1597/](https://xkcd.com/1597/)

