[HN Gopher] Git In Two Minutes (updated after 8 years)
___________________________________________________________________
Git In Two Minutes (updated after 8 years)
Author : garyrob
Score : 193 points
Date : 2022-08-06 18:03 UTC (4 hours ago)
(HTM) web link (www.garyrobinson.net)
(TXT) w3m dump (www.garyrobinson.net)
| ArrayBoundCheck wrote:
| I wish they made a breaking change in the next version and make
| the CLI actually usable.
|
| Before you downvote, ask yourself how do you list tags, branches
| and remote
| mmcclimon wrote:
| While acknowledging that git's CLI is often unintuitive: `git
| tag` lists tags, `git branch` lists branches, and `git remote`
| lists remotes, so I don't think I understand this particular
| objection.
| ArrayBoundCheck wrote:
| Compare it with `git branch -a` and `git remote -v`. That's
| my point. Not only are they all different flags but you'll
| get half the data you could be getting and not know why. It's
| impossible to google
| umanwizard wrote:
| They shouldn't break the existing `git` command as it is widely
| used in scripts. But there are projects that try to build
| better UIs on top of git; the most serious such attempt that I
| know of is magit.
| ajross wrote:
| "git tag", "git branch -a", "git remote -v"
|
| You point is what, that these are needlessly asymmetric? It's
| true. But they're in my head because I do them every day, and
| it's not like I'm suffering under the burden of remembering a
| handful of flags. That's a pretty far cry from "not actually
| usable", so maybe your hyperbole is a little misplaced?
| ArrayBoundCheck wrote:
| Correct. That was a simple example that's easy to understand
|
| Anyone with half a brain can understand that if they can't
| keep something as simple as printing a list consistent you
| better believe nothing else will be straightforward. Which is
| my point. NOTHING is straightforward and I haven't met a
| single person who likes the CLI if they do anything more
| complex than a commit, push and pull. I know people who still
| refuse to use rebase and don't understand bisect or blame.
| They use a GUI to restore files
| PeterWhittaker wrote:
| Branches are easy, what with them being only labels:
|
| > git branch --all
|
| Tags are different, since they are actual objects in git, but
| using ls-remote isn't tough, and one could create an alias.
| probably_wrong wrote:
| > _it it's enough be useful for beginning solo developers, and
| provides a start from which you can grow._
|
| I like this guide a lot as a cheatsheet. However, when it comes
| to beginners I fear it is one of those things that make sense
| only when you already know what the guide is talking about.
|
| It would take me more than two minutes just to explain a
| completely new developer what a commit is and why they would want
| one. And God help us if I throw the output of "diff" at them
| without warning...
|
| The sad truth is, you cannot explain git in two minutes. I
| nonetheless admire the author for giving the problem a fair
| fight.
| spaceman_2020 wrote:
| as a noob trying to pick up coding just to experiment with some
| ideas, I always found Git to be surprisingly confusing. I feel
| that a lot of the command names aren't very intuitive.
|
| Or am I just an idiot?
| garyrob wrote:
| I agree with you. What I do is use the snippets from the blog
| post without particularly thinking about them!
| sedatk wrote:
| Git is confusing. Alternatives like Mercurial are way more
| intuitive and easier to use, but they lack popularity.
| umanwizard wrote:
| I don't know whether you're an idiot or not, but thinking git
| is confusing is certainly not evidence to that effect.
|
| Git _is_ confusing; it became the de-facto standard because it
| was the first free DVCS (and DVCSs solve lots of problems that
| were common to old non-distributed VCSs), not because its UI is
| particularly well-designed.
| kadoban wrote:
| Git's command names, and UX in generaly, is its worst area.
| It's definitely not just you.
|
| Many professional software devs I work with still really have
| no idea how git works, they've just memorized the 3 or so
| commands they absolutely need and maybe how to recover when
| something out of the ordinary happens.
| probably_wrong wrote:
| When it comes to git, I am firmly of the opinion that it's not
| you, it's them.
|
| Git is simple, but it takes a lot of experience to appreciate
| its simplicity. So don't beat yourself up, git is _hard_ and it
| 's okay to be lost.
| sureglymop wrote:
| I think what makes it more confusing is that the inner workings
| are almost too simple.. so one wonders why there are so many
| commands etc.
|
| Git is basically a linked list (if you have one branch) and a
| graph (if you have more than one branch). Then all you are
| really working with are _pointers_ to certain nodes in that
| graph.
|
| In git terminology these nodes are called objects and there are
| different types of objects such as tree objects and commit
| objects etc. Objects are compressed with a library called zlib
| and are stored as files within the .git/objects directory, the
| file name is the hash of the decompressed object.
|
| But, back to the graph and the pointers to certain nodes. A
| branch itself is nothing more than a pointer either. You can
| look at the files in .git/refs/heads to see where they point.
|
| Now, what you do with git checkout is changing the node you
| currently view in the graph. If you make a commit you create a
| new node. Merging is nothing more than taking two nodes and
| creating a new node that is connected to both of them.
|
| The main problem i think is that concepts like branch, tag,
| commit etc are actually just overcomplicated abstractions of
| the much simpler graph nodes and pointers and are thus
| confusing.
| jonnytran wrote:
| Git isn't designed for "noobs trying to pick up coding just to
| experiment". It also isn't really designed for solo developers
| as the OP is about.
|
| Git is designed for collaboration. Git's UI is absolutely
| unintuitive, especially coming from other version control
| software. But that's irrelevant. Everyone wants to use it
| because of the network effect.
|
| In terms of _why_ the UI is unintuitive, I believe it's because
| it intentionally exposes its internal representation. Unlike
| its predecessors like subversion, Git has infinite flexibility
| in terms of the workflow that teams of people can adopt. But
| the flexibility comes at the cost of learning how to use a
| distributed graph of commits.
|
| Personally, I never learned git by reading recipes of commands,
| like the OP. I only really grokked it by understanding how it
| works internally. This article helped me:
|
| Git for Computer Scientists https://eagain.net/articles/git-
| for-computer-scientists/
| COMMENT___ wrote:
| > Git has infinite flexibility in terms of the workflow that
| teams of people can adopt.
|
| IMO flexibility is just a meaningless buzzword used to
| describe overly complicated and poorly designed products. If
| a product has crappy UX, they just call it "developer
| oriented" and "flexible".
|
| When I read about "flexibility" of a software product, I
| think that this product is of low quality. And that I will
| have to spend some time to make it work for me (hours? days?
| weeks? years?). To me as a user this flexibility does not
| matter at all.
|
| The product either works or it doesn't. If it works, I don't
| want to spend a career to learn its internals. I just want it
| to support my use case and give clear step by step
| instructions in its documentation.
|
| I better spend my time on something more important than
| exploring how this or another crappy software product is
| flexible.
| jimbobimbo wrote:
| I have 20+ years of professional experience and I'm using git
| via Visual Studio or VSCode UI. I'm not feeling ashamed of
| that.
| ducktective wrote:
| obligatory `lazygit` plugging. I do this because this project is
| criminally underrated: https://github.com/jesseduffield/lazygit
| garyrob wrote:
| About 8 years ago, I blogged a very brief guide to using git for
| a solo developer. A lot of people seemed to like it.
|
| A couple times since then, I've noticed there was something I was
| using that wasn't in it, but that could be added without making
| it significantly longer or more complicated. So there were a
| couple of updates.
|
| I did another one today, and had the thought that since this
| guide now includes the benefit of 8 years of practical experience
| in actually using it, while still essentially being "Git In Two
| Minutes", it might be worth posting to HN. So here it is.
|
| It doesn't say anything about github. It really is for a solo
| developer who wants to start using git in a very painless way.
| With the additional goal that you can profitably use git for
| years without going beyond the described features.
|
| https://www.garyrobinson.net/2014/10/git-in-two-minutes-for-...
| noja wrote:
| Without switch and restore, it is not modern git!
| boredemployee wrote:
| thank you very much. I'm always reluctant to read/watch _any_
| git tutorial, I think that will help me a lot!
| garyrob wrote:
| I hope it does!
| notRobot wrote:
| Thank you for this!
| moritonal wrote:
| Hey, just a heads up (won't be a problem for most people
| Goolging git) but on mobile (Firefox) the code blocks are
| almost unreadable because they're so small.
| boustrophedon wrote:
| In both examples given in the "Undoing a bad commit" section
| (fixing a commit message and fixing an error in a file) it's
| easier to make the change and then run `git commit -a --amend`
| which takes the current changes you have and adds them to the
| last commit, allowing you to change the commit message as well.
|
| There are other cases where git reset is useful, but generally
| not for the reasons given.
| carom wrote:
| How does this not mention git push? That and pull seem a lot more
| essential than everything that came after commit.
| nmz wrote:
| Absolute crap article.
|
| You don't learn git in two minutes if you don't talk about rebase
| and remotes.
|
| You want to learn a dvcs in 2 minutes? try fossil.
| demarq wrote:
| Guides like these are an absolute treasure when on-boarding
| junior devs.
|
| It can be really difficult distilling all you know about a
| certain topic into something short and concise like this.
| malkia wrote:
| Hey not only junior developers - there are senior ones (like
| me) that need it too! So thanks for all these "one-pagers" that
| are easy to remember.
| demarq wrote:
| haha but of course!
| candiddevmike wrote:
| Why do they have '--' as an argument in a lot of the commands? I
| don't think that's necessary?
| PeterWhittaker wrote:
| To quote TFM:
|
| > This option can be used to separate command-line options from
| the list of files, (useful when filenames might be mistaken for
| command-line options).
|
| This is a common idiom, e.g., to grep a file for a pattern that
| matches a grep argument,
|
| > grep -- -e file
|
| Edit: fixed dash weirdness.
| gizmo686 wrote:
| It forces git to intereperet what comes after as paths.
| Normally this is not needed, but occasionally you get a
| filename that causes ambiguity.
|
| For instance, "git checkout test.c" will check out the file
| test.c unless you happen to have a branch called "test.c". (See
| also people complaining that checkout is overloaded".
|
| Simmilarly, "git add --verbose test.c" will add test.c, and log
| that to stdout. "git add -- --verbose test.c" will add test.c
| and --verbose, where "--verbose" is the name of a file.
|
| This isn't git specific, most CLI tools use "--" to restrict
| the parsing on arguements that follow.
| soupshield wrote:
| What do we call the "--" part in a command like this:
| git checkout HEAD -- <filename>
|
| I find it hard to remember things unless I understand their
| purpose. It looks like it's specifying an argument but without an
| argument name (e.g. --verbose), unless it's similar to a pipe |
| symbol and <filename> is being passed to the checkout command as
| some special kind of argument?
| swordbeta wrote:
| https://unix.stackexchange.com/a/11382
| ttymck wrote:
| It is a delimiter indicating the end of options:
|
| https://unix.stackexchange.com/questions/11376/what-does-dou...
| gizmo686 wrote:
| I don't know what it is called, but it forces what comes after
| to be interpreted as a filepath.
|
| This is not git specific, but a common convention for CLI
| tools. Try running: > touch -- -i foo
| > rm -- -i foo
|
| And compare what happens without the "--".
| soupshield wrote:
| Thank you for this brilliant explanation (complete with
| interactive example :) I completely get it now.
| pojzon wrote:
| Not only a filepath, this means pass anything past "---" 'as
| is' as an input and not an option flag.
|
| docker run -it nginx --- ls la
| soupshield wrote:
| Ah yes I've seen it in those kind of contexts too. Thanks
| everyone this has really clicked in to place for me :)
| drdec wrote:
| Not a file path specifically and not an input exactly but I
| think the proper word would be an argument.
| tremon wrote:
| And then we have startx, which starts both an X server and
| the X client specified: startx
| /path/to/client --with --client-options and arguments --
| --server-options -go --here
|
| Here, the double dash is used to separate the client options
| from the server options (the path to the server binary is
| compiled-in, IIRC).
| wruza wrote:
| It means "stop processing arguments as options and leave them
| alone" to getopt-likes. E.g. to rm file named "-f":
| rm -- -f
|
| Idk the word, just minus minus.
| soupshield wrote:
| > E.g. to rm file named "-f":
|
| I've defintely had this sort of problem in the past :)
| vultour wrote:
| rm ./-f
| kelthuzad wrote:
| I found the "Missing Semester" lectures on YouTube to be pretty
| helpful:
|
| Regarding git there is:
|
| Lecture 6: Version Control [0]
|
| [0] https://youtu.be/2sjqTHE0zok
| anderskaseorg wrote:
| These days it might be better to teach new users about 'git
| switch' and 'git restore' (added in Git 2.23, released
| 2019-08-16) rather than the two overloaded meanings of the
| confusing 'git checkout' command.
|
| https://git-scm.com/docs/git-switch
|
| https://git-scm.com/docs/git-restore
| ajross wrote:
| My feeling is that new users shouldn't be taught about branches
| in their local repo at all. Typical cloud-based
| git{hub,lab}/gerrit/etc.. workflows generally store all
| branches worth talking about on remote systems anyway.
|
| I find I don't ever bother with managing local branches for
| anything in my own workflows. I just git-reset --hard to bounce
| between fetched copies of upstream branches as needed. Stuff I
| need to work on for more than a few commits in an afternoon
| gets pushed to a remote branch regularly anyway as part of
| general safe development hygiene.
| chasil wrote:
| My developers use CVS.
|
| Sometimes, they are really stupid, and they will checkin
| passwords.
|
| With the RCS archives, I can use vi (or nano, or any other
| reasonable editor), and remove this foolishness.
|
| When I run "git cvsconvert" any foolishness is _ENGRAVED IN
| STONE_.
|
| Removal is possible in git, but not easy.
|
| This is my problem. THERE ARE SO MANY IDIOTS. What can I do?
|
| EDIT: For Windows-centric users of git, you need to run this in
| every and all repositories RIGHT NOW.
|
| git grep -i password $(git rev-list --all)
|
| [actually, everybody should try it]
| AnonCoward42 wrote:
| I might be an idiot myself, but would `git rebase -i
| <commitBeforeSnafu>` do the trick?
|
| edit: This is interactive rebase, where you can rewrite
| history. Instructions are in the file you are editing once
| the command is executed. As a rule of thumb, don't rebase on
| production, however with such a SNAFU you probably need to.
| gizmo686 wrote:
| No. The old commits still exist, a rebase just makes it so
| that they are not part of the history of the current
| branch. If you know the commit hash of a commit containing
| the offending data, you can still check it out. You can
| also find such commits in the reflog, or if they are part
| of the history of any other branch or tag. The data is also
| in git's internal data structures if you know enough to
| interpret those directly.
|
| Still, a rebase is a critical part of fixing this. If you
| rebase every branch that has the offending data in their
| history, and recreate any tags that have the data, then the
| offending data would be present only in unreachable objects
| (which can still be found through the reflog or knowing a
| commit hash). Eventually, git's garbage collection will
| clean up such unreachable data. You can force this
| behaviour earlier by using the `git gc` command. By default
| git will not remove recent objects (which is why you can
| reflog your way out of a botched rebase), but you can
| override this behaviour as well.
|
| Of course, all of the above assumes you are working on your
| own repository. Given git's decentralized design, you need
| to clean up and garbage collect on every clone that did a
| fetch since the offending data was checked it. Worse, each
| clone also keeps track of remote branches, and considers
| those to be reachable as well, so a garbage collection will
| not work correctly until a given clone fetches from all of
| its remotes after those remotes removed the offending data
| [0].
|
| Further, there is not good tooling to check that you
| actually did this correctly, so when you are done, you need
| to hope you fully purged the data.
|
| The plus side of all of this is that once something is
| checked in, it is extremely difficult to accidently delete
| it. The downside is that it is also difficult to
| deliberately delete it. Also, it is fairly easy to make it
| difficult enough to find to negate the day to day benifets
| of it still existing, which does very little to protect
| against a motivated attacker.
|
| [0] Fourtuantly, you do not need all of the remote to have
| garbage collected, so you could have every make the data
| unreachable, fetch on all remotes, then garbage collect.
| ramadis wrote:
| Chill?
| chasil wrote:
| What is really far more critical to understand is that my
| vi changes what everybody sees in CVS.
|
| If there is some foolishness, git propagates it EVERYWHERE.
|
| Every git repository is equal. I have no control of
| proliferation.
|
| Sigh.
| alvarlagerlof wrote:
| It's more useful to fix the problem before it happens.
| Try to set up systems or workflows that make it easy to
| do the right thing, rather than trying to fix it
| afterwards.
| pluijzer wrote:
| You can try and talk to your developers with more respect.
| People make mistakes and don't have to be idiots or stupid
| for it.
|
| edit: mistakes happen always it is better to change the
| workflow in such a way that a the consequences can be
| contained.
| chasil wrote:
| They quit far too much for any rapport.
|
| I have to walk them through configuring an ssh agent
| (usually devolving to pageant.exe) and they are gone in
| three months.
|
| Kind of a big ask.
|
| EDIT: I do love my job. People? Uh...
| paraknight wrote:
| "If everywhere you go smells like shit, maybe it's time
| to check your own shoes"
| electrondood wrote:
| > They quit far too much for any rapport.
|
| The developers you publicly describe as stupid and idiots
| seem to leave every three months. Huh.
| orf wrote:
| Fix whatever processes, tooling, culture or training _you_
| have that leads _your_ developers to make these mistakes
| sxg wrote:
| Multiple people committing the same mistake is much more
| likely to be a systems problem rather than an individual
| developer's problem.
|
| The other reply comments are saying the same thing, but your
| (parent) comment needs to be called out.
| [deleted]
| lstamour wrote:
| Stop using any passwords that get checked in. Set expiry
| dates for access tokens. Set up git commit hooks that scan
| for password or API key prefixes and block the commit. Set up
| appropriate .gitignore files, you can place them in
| subfolders to keep them simple.
|
| If possible, switch from using passwords or tokens without
| expiry to using ephemeral or time-limited tokens such as
| machine or pod identities, JWT tokens, IAM service accounts,
| public/private key pairs (if you can get by with only a
| public key in the repo) or two-factor authentication.
| Consider distributing time-limited passwords with Hashicorp
| Vault.
|
| Some teams might use a cloud-hosted secrets manager or
| password manager like 1password to distribute passwords and
| then have code load the password as it runs on a developer
| machine. GitHub has a secrets scanner, if you pay them enough
| money for "Advanced Security" such that secrets can never be
| pushed upstream if recognized as such.
|
| Also, converting from any repo format to another repo format
| requires care and multiple repeated attempts. A lot can go
| wrong. Reposurgeon (from a sibling comment) is highly
| recommended but also not easy to use. It takes a lot of
| attention to detail to really get the details right.
| User23 wrote:
| Git filter-branch will erase your shame. But as others have
| said, those credentials are burnt and need to be treated
| accordingly.
| CrazyPyroLinux wrote:
| These days https://github.com/newren/git-filter-repo is
| superior.
| chasil wrote:
| Just kill me now.
|
| We had the same problem in TFS.
|
| I found them, I warned them, my riot got us kicked off our
| shared server.
|
| We migrated to our corporate TFS cloud, and they kicked us
| off for precisely the same reason.
|
| This just won't/can't stop.
| tigerlily wrote:
| Don't use cvsconvert. Use reposurgeon, you will get much more
| fine grained control.
|
| Here's a brief precis on getting started: https://gist.github
| .com/ryfactor/f70529438f254d44c0077176508...
| chasil wrote:
| I don't think that we will move, and I likely will not
| assume TFS, but I will look.
| garyrob wrote:
| I'll look into that, thanks!
| garyrob wrote:
| I'm going to think about this more. Ironically, I'm in a
| situation for a few days where I can't really focus on
| technology.
|
| It sounds like switch and/or restore are probably stable enough
| that they could be used instead of checkout for the specific
| tasks I'm trying to do in the blog post, so yet another update
| will be warranted when I get a chance!
|
| It's completely usable as-is, so I hope no one is scared off by
| thinking it should incorporate switch and/or restore. It's
| usable now, and if you do feel like saving a link to it for
| future reference, I expect that there will be another way in
| the future to do a couple of the tasks using the more modern
| syntax.
| malkia wrote:
| First of all, I'm long time going git n00b (still mainly p4,
| and g4 for a bit user), but welcome any hints to easy going
| with git (have to use it occassionally).
|
| Saw this though for switch/restore:
|
| "THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE."
| ilyagr wrote:
| I, personally, learned to use git a couple of years ago, have
| never learned to use the `checkout` command, and had no need
| for it. The goal of `switch`/`restore` is to do everything
| that `checkout` does while being less of a confusing mess.
|
| See also the reddit thread linked by a nephew comment.
| garyrob wrote:
| Hmm, maybe I should leave as-is, for the time being, anyway!
| Thank you!
|
| Update: based on other comments, I WILL seriously look into
| replacing the use of checkout. It sounds like these newer
| features are probably stable enough for the simple things
| that are being done in the blog post, and that updating the
| post will more it a bit more useful as a starting point for
| learning git.
|
| I'm thinking of posting the modern syntax as an alternative
| rather than a replacement to checkout, but I have yet to
| investigate how stable things are now... will do when I have
| time.
|
| But meanwhile, the checkout method is fine, it works, and
| it's well-established for many years.
| NoahKAndrews wrote:
| I think this Reddit comment has the right idea, especially
| now that those commands have been released for 3 years: htt
| ps://www.reddit.com/r/git/comments/ifkbfz/comment/g2on6yo..
| .
| malkia wrote:
| Thank you, and that's a good advice from the comment:
|
| "So if you're writing a script that needs to work with
| dozens of past and future Git versions, use git checkout.
| If you need to teach humans how to talk to Git, use git
| switch. Some details of some flags may change in the
| future, but I'd argue that that'll be a smaller mental
| challenge than trying to teach which parts of git
| checkout do what."
|
| I'll try to use more switch/restore
|
| I've actually used "git stash" more than it should be
| (I'm probably applying real bad "p4/g4/svn" like ideas in
| my head to the development. As soon as I go into project
| with few more people, and I'm lost, though I was able to
| make few PR's in github for things - but everytime had to
| le-learn the process).
| ziml77 wrote:
| I sometimes use git stash as a safer alternative to git
| reset --hard HEAD. git stash -> check that the state
| you've reverted to is actually what you want -> git stash
| drop. And since internally stash is just creating a
| commit, it's even possible to recover the changes if they
| haven't been garbage collected.
| noSyncCloud wrote:
| Only used Git and SVN before, sorry for noob question. I
| guess p4 is Perforce, but what is g4?
| wizofaus wrote:
| I only found out about git switch recently - super handy when
| you want to checkout another dev's branch that isn't tracked
| locally yet. There's a case to be made for reserving 'checkout'
| for when you specify a filespec rather than a branch.
___________________________________________________________________
(page generated 2022-08-06 23:00 UTC)