top | item 29978336

Learn the workings of Git, not just the commands (2015)

130 points| philonoist | 4 years ago |developer.ibm.com | reply

94 comments

order
[+] throw0101a|4 years ago|reply
It's been over a decade and I still find this joke amusing:

> @wilshipley git gets easier once you get the basic idea that branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space.

* https://twitter.com/agnoster/status/44636629423497217

(It's a 'spoof' on the Monad joke.)

[+] avn2109|4 years ago|reply
Mandatory plug for the best git docs on the internet: https://git-man-page-generator.lokaltog.net

For example, ```git-dissect-tipdissects indexed local tips from all noted downstream upstreams, remotes commit graphs, etc.```

Anytime somebody is confused or stuck with Git, it's a great idea to helpfully send them some documentation links from there.

[+] zibzab|4 years ago|reply
Why does any post discussing _any_ aspect of git always results in these type of comments? "git is complex", "git command line is confusing me", "life would be easier is we all used subversion".

Please let us discuss git in peace.

(Although I admit that this one was funny)

[+] zibzab|4 years ago|reply
A mucher better explanation of git interals:

https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

It is surprisingly simple and efficient. I am starting to think this Linus guy knows what he is doing.

[+] kwertyoowiyop|4 years ago|reply
He offloaded the complexity to its users! :-)

If the command and option names had just been sensible, it would be a lot easier to learn and use. Half the usability difficulty, maybe more, is just this.

[+] NalNezumi|4 years ago|reply
I like the attitude of "learn the principles of the simple building blocks behind it" as a good next step from a freshman that just memorized "add, commit & pull/push"

But most headache (and heartattack) inducing part of Git when I was a beginner was the "remote vs local repo" and additional complexities this concept introduced. Nothing more stressing for the new guy than making mistakes that screw up for others (mistakeful push, merge, mostly ) or if he think he did.

The article does a poor job (imo) regarding this. It skims on a 2 paragraph "Caveat" section how rebase(and later squeeze) can fuck local vs remote repo, but for most people I know, stress memories around this is what made them learn more about Git beyond than "branch & history keeping software & commands.

That and if you unfortunately end up in a project that uses subtree or submodules

[+] kwertyoowiyop|4 years ago|reply
“You need to use git diff --cached to see what is actually in the index: the staged changes.”

Like LOTR, everyone has more than one name.

[+] speed_spread|4 years ago|reply
Git's CLI is it's greatest weakness. Someone should really just scrap that part and rebuild it from scratch on sane ground.
[+] dahart|4 years ago|reply
And, unfortunately, the CLI is git’s greatest strength as well. Git was designed for the command line only truly flourishes there, for advanced workflows. The GUI tools that wrap git, and web interfaces like github, only provide access to a subset of what git can do.

It’d be interesting to see what a good redesign might look like. I do think some of the command names and command flags could be superficially updated/renamed/moved and provide a meaningful impact on git’s usability and learning curve. I’m curious though about whether the conceptual part of git is the primary source of difficulty, whether git is fundamentally a little hard to learn, because it’s fundamentally a little bit complex. If that’s the case, a rebuild might not help, there might not exist the kind of “sane ground” to build on that you hope for.

[+] trabant00|4 years ago|reply
For 20 years I keep hearing these types of complains about Git, Perl, GPG, etc. If you really need those tools than things like syntax, arguments and flags need a little time investment, but after a while they become second nature and you don't even think about them, but about the hard problem that is being made possible to solve by said tools.

These are not toys, one should not expect to just jump into them and start doing work like you would not just jump into a Boeing 747 and just take off, fly and land. It having 100s of buttons is not a weakness.

[+] pfarrell|4 years ago|reply
Poe's Law is getting me on your comment. If it wasn't sarcasm, what's an example of a weakness? IMHO, there's a learning curve to using git and especially getting to the point where you can be your team's go-to person for git questions. However, I hold the opinion that of the many technologies out there, git is among those that is worth any investment you can make in learning it. Personally, long term use of git has affected the way I code to bring more intention and organization to what I'm doing.
[+] dragonwriter|4 years ago|reply
> Git's CLI is it's greatest weakness

Git’s CLI is good as a unix-philosophy low-level tool that user-friendly tools can build on, and is a strength in supporting a wide range of different workflows.

It's suboptimal as a end-user tool for most workflows, but not bad enough for that people consistently build tooling rather than guides for particular workflows.

[+] delecti|4 years ago|reply
Understanding what git is doing under the hood did more for my ability to use it effectively than it did for most tools.

That said, this document in particular does not seem to be a very good way to get that understanding, it's a very "IBM documentation" way of presenting git. I wish I remembered what I read, because it's was a much easier read.

[+] boppo1|4 years ago|reply
Maybe the git man pages? Iirc the man pages have 2 or 3 'getting started' documents that really made me feel confident. Then I didn't use it for two years and now it's real fuzzy again.
[+] jpindar|4 years ago|reply
I found the Git section of "The Missing Semester of Your CS Education" to be helpful.
[+] zelphirkalt|4 years ago|reply
In my experience it is fine to first learn only some required commands. One will run into cases, where ones understanding or imagination of how git works will not work any longer. In such cases one can still read up on how it works and build a new working understanding. Only important to not always just shrug, delete the repo and clone again. That will not really facilitate learning.

Of course no one is stopping anyone interested in it from reading more about how it works up front.

[+] wmf|4 years ago|reply
This usually leads to "my shit's due in an hour, my repo is totally broken and I have no idea why... HEEEEELP".
[+] taubek|4 years ago|reply
I'm new to git. For now I use it from VSC, but I should probably give CLI a chance.

I must admit that I'm at the point where I shrug, delete and clone the repo if I'm stuck. Some errors and messages were to cryptic to me.

[+] erwincoumans|4 years ago|reply
"In this case, the conflicting result is left in the working directory for the user to fix and commit, or to abort the merge with git merge –abort."

I've used git for many years, and I still zip the repo folder, before doing a large merge, since 'fix the commit' can be a large effort with conflicts. Quickly renaming the repo root folder, then unzipping the old version can be quicker/safer, if you are not a git ninja and don't want to loose any work. There is probably proper command for it, but I sometimes get into a git mess that I cannot get out of. (reading stack overflow, trying get reset, git checkout, git reset --hard and so on)

[+] balefrost|4 years ago|reply
Quick tip: Git branches are cheap. Like super-cheap. IF you want to create a safe point just before doing a tricky merge, just spin off a new branch pointing at the current commit:

git branch blah_branch_backup

Later, if your merge gets completely messed up, you can do:

git merge --abort

git reset --hard blah_branch_backup

That final command will restore the current branch's HEAD to point to the same commit as blah_branch_backup.

This same pattern is useful for other dangerous commands, like rebases or filter-branch.

When you're done, just delete blah_branch_backup.

[+] dahart|4 years ago|reply
> There is probably a proper command for it

Before you merge, the command is “git merge --abort”. After you merge, the command is “git reflog” to show your history, and then something like “git reset --hard HEAD@{1}” where the number in braces is the reflog entry you want to restore.

Reflog is the ultimate undo tool for work that’s been committed, it’s like having an infinite Ctrl-Z. If you use reflog to restore before your merge, you can even use it again to restore your mess, or to restore a different merge before the one you made a mess of.

The one thing you can’t recover using reflog is an accidentally dropped git stash. This is one reason I try to avoid stashes, and just use lots of one-off branches instead.

[+] commandlinefan|4 years ago|reply
I'm the same - although I've had many experiences in the past where I avoided the time-saving tools because they were too complex in the moment and then kicked myself later on when I realized just how much time I had been wasting by avoiding spending ten minutes learning the time saving tools, every time I try to do a git merge "the right way", I end up with conflicts that shouldn't be conflicts and changes that I didn't want to pull in that I have to manually undo until I just give up and "manually" merge.
[+] globular-toast|4 years ago|reply
"Zipping the folder" and keeping a copy of it is literally the sole purpose of a version control system. These kind of comments baffle me, quite honestly. But that is my fault, not yours.

Could you tell me what you think git is for and why you use it?

[+] zoomablemind|4 years ago|reply
As a user, I see absolutely no reason to know the internal workings of Git. It supposedly offers a service, which is tracking and recording changes to files. In a way, it's a very able SaveAs/Open command and also offering some way of altering the recorded history.

How it's done internally, as much as it's remarkable, is just an implementation detail. The fact that users are repeatedly being referred to docs/books, points to conceptual inconsistencies or mismatches in the intended application contexts.

As a user I operate with directories and files. Now version control also introduces a time-component, which is versions (and version of a version aka branch) and some kind of history/timeline/journal/log.

Why would a branch have a "head" and "base", isn't parent/child concept expressive already? Why "ref", if we've got "version" already? Why "stage", "index", "cache"? Why "cherry-pick" if we've got "patch"? Etc.

[+] shxdow|4 years ago|reply
One reason why you would want to know how Git internally works is to make a better use of it. The interface it exposes is relatively low level and as such suffers when uses don't understand how the software internally operates. If anything, used being repeatedly pointed to docs shows the lack of understanding of Git's inner workings.
[+] enriquto|4 years ago|reply
As much as I love and depend on git, the visible user interface seems a bit ugly. You can get used to it over time, but it has a certain non-unix flavor that I dislike...

There should be a purely unix way to use git, as in "everything is a file". Sure, you can go to the .git folder and there are files in there. But the structure of these files does not directly represent the structure of the repository. What I want is to "mount" a git repository, so that I can explore its contents using cd, ls and cat. Also, by editing these files I implicitly make commits and create branches to the underlying structure. Would that even be possible?

EDIT: A disturbing feature that I don't see a way out is that in git there are "standard" and "history-rewriting" operations, and there is a clear distinction between the two. To what would that correspond in terms of pure file operations? Something about changing the default permissions?

[+] cryptonector|4 years ago|reply
> A disturbing feature that I don't see a way out is that in git there are "standard" and "history-rewriting" operations, and there is a clear distinction between the two. To what would that correspond in terms of pure file operations? Something about changing the default permissions?

> "history-rewriting" operations

Git is a Merkle hash tree. You can never rewrite history. Instead, what you think of as "history-rewriting" operations is just "non-fast-forward" changes to branches. Branches are really just named pointers -- {branch_name, commit_hash}. A change to branch from {$name, $commit0} to {$name, $commit1} is fast-forward IFF $commit0 appears in the linear history of $commit1. A non-fast-forward change to a branch is what you call a "history-rewriting" operation.

There's nothing wrong with "history-rewriting" -- I do it all the time. It's only ever bad when you do a non-fast-forward push to a branch that others track, and even then it's not the end of the world because usually those others can recover easily enough with `git rebase --onto`. Rewriting the history of a public branch is a problem, yes, because you want the history to be stable and reliable so you can use it to figure out problems, understand the history of the project, etc, and because making others have to `git rebase --onto` is impolite.

It's essential to understand that the only destructive operations in git are a) non-fast-forward branch changes, b) tag changes, c) gc/prune operations when you're like me and you're used to working in detached-HEAD mode.

If you're stuck on "Git has history rewriting, and that's bad!", then you've misunderstood everything about modern version control systems. You can -and I have- do the same sorts of destructive operations in version control systems going back to the early 90s (e.g., Teamware, CVS), to say nothing of newer ones like Mercurial, Fossil, and, of course, Git.

Inb4 "But Git encourages history rewriting" -- that is neither true nor a good argument.

[+] dogleash|4 years ago|reply
> What I want is to "mount" a git repository, [...] Would that even be possible?

Yeah, sure, why not? You could do it with fuse http://libfuse.github.io/doxygen/ There's even a git fuse filesystem already out there. I dunno if it works the way you want though.

[+] mikewarot|4 years ago|reply
If I might offer a suggestion, instead of using various git commands, you want to be able to just cp a folder to a mounted git folder, and echo the commit message to a .commitmsg in that folder, or something like that, right?
[+] pjam|4 years ago|reply
Feeling required to post about the Building Git[1] book, really love it, for anyone interested in a walkthrough of rebuilding many of the most of important git features, from scratch, in ruby.

[1]: https://shop.jcoglan.com/building-git/

[+] glynnormington|4 years ago|reply
Excellent! Two updates since it was written: use main rather than master for the default branch; use git switch to change or create branches.
[+] aasasd|4 years ago|reply
Pffft, as if anyone actually could just use Git commands without learning the internals.
[+] DarkWiiPlayer|4 years ago|reply
The important thing to understand is that git is a blockchain
[+] globular-toast|4 years ago|reply
It goes a lot further than just being a blockchain. Git is a DAG through and through. But this might actually be the best way to make some people understand it. I was gobsmacked one day when a colleague came into work and they were really excited as they'd realised git is actually a blockchain. I was stunned as it seemed so obvious, but if they only just realised then how had we been working successfully with git for so long?
[+] kwertyoowiyop|4 years ago|reply
So each commit is an NFT. Now, where’s my million dollars?