[HN Gopher] Oh Shit, Git?
       ___________________________________________________________________
        
       Oh Shit, Git?
        
       Author : Anon84
       Score  : 421 points
       Date   : 2025-01-16 18:24 UTC (1 days ago)
        
 (HTM) web link (ohshitgit.com)
 (TXT) w3m dump (ohshitgit.com)
        
       | divbzero wrote:
       | This is old school. No switch or restore here.
        
       | pitaj wrote:
       | Some changes I would make:
       | 
       | 1. Always use `git switch` instead of `git checkout`
       | 
       | 2. Avoid `reset --hard` at all costs. So for the "accidentally
       | committed something to master that should have been on a brand
       | new branch" issue, I would do this instead:                   #
       | create a new branch from the current state of master         git
       | branch some-new-branch-name         # switch to the previous
       | commit         git switch -d HEAD~         # overwrite master
       | branch to that commit instead         git switch -C master
       | # switch to the work branch you created         git switch some-
       | new-branch-name         # your commit lives in this branch now :)
       | 
       | 3. I'd apply the same to the `cherry-pick` version of
       | "accidentally committed to the wrong branch":
       | git switch name-of-the-correct-branch         # grab the last
       | commit to master         git cherry-pick master         # delete
       | it from master         git switch -d master~         git switch
       | -C master
       | 
       | 4. And also to the "git-approved" way for "Fuck this noise, I
       | give up.":                   # get the lastest state of origin
       | git fetch origin         # reset tracked files         git
       | restore -WS .         # delete untracked files and directories
       | git clean -d --force         # reset master to remote version
       | git switch -d origin/master         git switch -C master
       | # repeat for each borked branch
        
         | lalaithion wrote:
         | The disconnect between git's beautiful internal model of blobs,
         | a tree of commits, and pointers to commits, and the command
         | line interface is so wild. All of these recipes are unintuitive
         | even if you have a firm grasp of git's model; you also need to
         | know the quirks of the commands! To just look at the first
         | one... wouldn't it be more intuitive for the command line
         | interface to be:                   # this command exists
         | already;         $ git switch -c some-new-branch-name         #
         | is there a command that simply moves a branch from one commit
         | to another without changing anything else? It feels like it
         | should be possible given how git works.         $ git move-
         | branch master HEAD~
        
           | pitaj wrote:
           | I prefer just using `git switch` because it's easy to
           | remember the flags (and the position of arguments), but
           | you're right, there is a simpler way:                   git
           | switch -c some-new-branch-name         git branch -f master
           | HEAD~
        
             | DangitBobby wrote:
             | You should also be able to do                 git branch -f
             | master origin/master
        
               | pitaj wrote:
               | This doesn't work if your local master was already ahead
               | of origin
        
               | DangitBobby wrote:
               | Indeed, as with all of these examples exceptions will
               | apply and, it's a good idea to check the log before
               | taking any such action. I believe your example also
               | depends on exactly how many commits you've made that need
               | to be moved. In any case, it depends on me remembering
               | exactly what `~` signifies.
        
             | lalaithion wrote:
             | Good to know! Thanks for the tip.
        
           | neild wrote:
           | The "move a branch from one commit to another without
           | changing anything" command is "git reset".
           | 
           | "git reset --hard" is "...and also change all the files in
           | the working directory to match the new branch commit".
           | 
           | "git reset --soft" is "...but leave the working directory
           | alone".
        
             | rav wrote:
             | Actually, "git reset --soft" moves the current branch to
             | another commit, without moving the index (aka staging area)
             | along with it, whereas "git reset" (aka "git reset
             | --mixed") moves the current branch AND the index to another
             | commit. I really couldn't wrap my head around it before I
             | had gone through "Reset demystified" [1] a couple times -
             | it's not a quick read but I can strongly recommend it.
             | 
             | [1] https://git-scm.com/book/en/v2/Git-Tools-Reset-
             | Demystified
        
             | lalaithion wrote:
             | git reset only works if you're on the branch you want to
             | move, which is why every one of these example flows has you
             | create your new branch, then do the reset, then switch to
             | the new branch, instead of just allowing you to move a
             | branch you're not on.
        
           | rav wrote:
           | For move-branch: Use `git branch -f master HEAD~` if you're
           | currently on another branch, or `git reset --soft HEAD~` if
           | you're currently on master.
        
           | Certhas wrote:
           | The real "internal model" of git contains much more
           | data/moving parts.
           | 
           | There isn't one tree of commits, there are typically at least
           | two: local and remote
           | 
           | Branches are not just pointers to commits, but also possibly
           | related to pointers in the other tree via tracking.
           | 
           | Stash and index and the actual contents of the working
           | directory are additional data that live outside the tree of
           | commits. When op says "avoid git reset hard" it's because of
           | how all these interact.
           | 
           | Files can be tracked, untracked and ignored not ignored. All
           | four combinations are possible.
        
             | lalaithion wrote:
             | None of these seem to preclude a command to make an
             | arbitrary branch point to an arbitrary commit without
             | changing anything else.
        
               | fragmede wrote:
               | This works if the branch exists or creates it if it
               | doesn't exist, but not if it's checked out.
               | git branch -f branch_name commit
               | 
               | if it's checked out:                   git reset --hard
               | commit
        
               | seba_dos1 wrote:
               | > but not if it's checked out
               | 
               | ...and for a good reason that should be apparent to
               | anyone who understands git's model (HEAD points to a ref
               | in this case, so if you suddenly change what that ref
               | points to without updating the working tree you create an
               | inconsistency).
               | 
               | You can do that manually of course (with `git update-ref`
               | or even a text editor), but then you get to clean up the
               | mess yourself.
        
               | thfuran wrote:
               | Couldn't head just detach without any consistency issue?
        
               | seba_dos1 wrote:
               | Theoretically it could, but that would be a rather
               | surprising side effect. You could also check the new
               | revision out and leave HEAD intact. Which one of those
               | outcomes you would expect and why?
               | 
               | "error: ref in use by higher layers" makes much more
               | sense to me in this case.
        
               | Certhas wrote:
               | If you buy the "git is just a tree of commits and
               | pointers" mental model it's absolutely not a surprising
               | side effect but would be the logical thing to expect. I
               | moved a pointer to a commit around, why would that change
               | where HEAD is pointed.
               | 
               | Turns out it's a tree of commits and pointers to within
               | that tree and a master pointer that come in two versions:
               | pointing towards the pointers or pointing towards the
               | tree. And pointers behave very differently when the
               | master pointer is pointing to them...
               | 
               | Elegant. Simple. :P
        
               | seba_dos1 wrote:
               | > I moved a pointer to a commit around, why would that
               | change where HEAD is pointed.
               | 
               | ...because HEAD points to what's checked out. This
               | pointer does not just exist and hang around, it has its
               | semantics. Not understanding that reveals flaws in your
               | mental model.
               | 
               | Besides, the side affect you find "not surprising" here
               | is... rewriting HEAD to change what it points to. Then
               | you ask "why would that change where HEAD is pointed".
               | Sounds like you may be confused. Are you forgetting that
               | a ref may point not just to a commit, but also to another
               | ref? This is the _whole idea behind branches_ after all,
               | having HEAD point to a ref is exactly what makes branches
               | semantically different from tags - if you don 't
               | understand it then no wonder you're confused.
               | 
               | When a pointer is in use by higher layers, a good UI will
               | prevent you from making direct changes underneath it
               | unless you force it or go low-level enough for it to not
               | matter. The only sin of git I can see here is that `git`
               | command provides you both high-level and low-level
               | interfaces to manipulate the data structure you're
               | working on with no clear distinction for the user.
        
               | thfuran wrote:
               | It doesn't seem surprising to me. It probably ought to
               | print ought a warning that head has detached though, like
               | some other commands already do. That error message on the
               | other hand seems very unhelpful. It's lingo that only
               | makes sense if you're neck deep in the plumbing.
        
               | seba_dos1 wrote:
               | There's no such message there, it was a description of
               | situation written by me. Should have made it clearer I
               | guess.
               | 
               | It is surprising. You wanted to edit the value of `main`
               | ref, yet suddenly you now edited `HEAD` too without
               | meaning it. Bailing out and letting you actually decide
               | whether you want to do it or not is the correct thing to
               | do for a high-level command like `git branch`
               | (alternatively it could ask you what to do
               | interactively). If you don't want such safeguards and you
               | know what you're doing, use `git update-ref` which will
               | happily let you break whatever you want.
        
               | Certhas wrote:
               | To me that looks like git is leaking implementation
               | details left and right.
               | 
               | So much for "a branch is simply a pointer to a commit"...
        
               | seba_dos1 wrote:
               | Do you react the same way when an OS prevents you from
               | writing to a file with an exclusive lock placed on it? So
               | much for "a file is simply a collection of data stored as
               | a single object"...
               | 
               | If a git repo was purely a collection of meaningless
               | pointers and graph nodes, git would be a graph
               | manipulation utility, not a version control system. The
               | fact that some of those pointers have a meaning is what
               | makes it useful and it doesn't contradict the fact that
               | what you're working on is still just a bunch of pointers
               | and nodes.
        
               | karatinversion wrote:
               | You are looking for                 git update-ref
               | <branch-name> <commit-sha>
        
               | DiggyJohnson wrote:
               | Wouldn't the fail or break under any circumstance where
               | they don't immediately share a history?
        
           | jimbokun wrote:
           | Are there alternative git command lines that keep the
           | beautiful internals, but implement a more elegant and
           | intuitive set of commands to manage it?
        
             | dalia-reds wrote:
             | Check out jujutsu or jj (same thing). It's its own VCS, but
             | it uses git as a backend, so it works with GitHub and other
             | git integrations
        
             | stouset wrote:
             | Seconded jujutsu. It's 100% git-compatible and one of those
             | rare birds that is both _more powerful_ and simpler to use
             | in practice due to rethinking some of the core ideas.
        
             | maleldil wrote:
             | Another vote for jujutsu. No one else needs to know you're
             | using it. You can think of it as just a different CLI for
             | git (although you shouldn't mix them). I used to use third-
             | party interfaces like lazygit, but I don't need them
             | anymore because jujutsu _just makes sense_.
        
             | jonasced wrote:
             | Lazygit has a terminal UI but might otherwise be what
             | you're looking for:
             | https://github.com/jesseduffield/lazygit
        
           | Terr_ wrote:
           | > The disconnect between git's beautiful internal model of
           | blobs, a tree of commits, and pointers to commits, and the
           | command line interface is so wild
           | 
           | Something I heard somewhere that stuck with me: git is less
           | less of a Version Control System, and more of a toolkit for
           | assembling your own flavor of one.
        
             | JadeNB wrote:
             | > Something I heard somewhere that stuck with me: git is
             | less less of a Version Control System, and more of a
             | toolkit for assembling your own flavor of one.
             | 
             | That's how it is in principle, but it seems to me that
             | there aren't that many different CLI "porcelains" in
             | practice. Kind of like how Knuth figured people would
             | essentially write their DSLs on top of plain TeX, not spend
             | most of their time in giant macro packages like LaTeX.
        
               | dragonwriter wrote:
               | > That's how it is in principle, but it seems to me that
               | there aren't that many different CLI "porcelains" in
               | practice.
               | 
               | I think that's because most of the people that make
               | custom tooling to support particular workflows build it
               | into graphical (including IDE extensions, web-based.
               | etc.) frontends, not CLIs.
        
           | lilyball wrote:
           | The "move a branch" command is `git push .`. Yes, you can
           | push to the current repo. I have a script called git-update-
           | branch which just does some preflight checks and then runs
           | `git push --no-verify . +$branch@{upstream}:$branch` to reset
           | a branch back to its upstream version.
        
             | zahlman wrote:
             | > The "move a branch" command is `git push .`. Yes, you can
             | push to the current repo.
             | 
             | Wouldn't that copy a branch rather than moving it?
        
           | assbuttbuttass wrote:
           | > is there a command that simply moves a branch from one
           | commit to another without changing anything else? It feels
           | like it should be possible given how git works.
           | 
           | git switch -C master HEAD~
        
         | CharlieDigital wrote:
         | What's the problem with `reset --hard`?
        
           | pitaj wrote:
           | It leaves behind tracked files that were moved or deleted
           | between revisions.
        
         | mrshu wrote:
         | Not trying to defend the choice of `git checkout` over `git
         | switch` (and `git restore`) but they were introduced in v2.23
         | of Git [0], which was released about 5 years ago [1]. If you
         | take a look at their help pages, they still include a warning
         | that says
         | 
         | > THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
         | 
         | Granted, it has been in there for basically as long as the
         | command(s) existed [2] and after 5 years perhaps it might be
         | time to no longer call it experimental.
         | 
         | Still, it does seem like `git checkout` might be a bit more
         | backwards compatible (and also reflective of the time when this
         | website was originally created).
         | 
         | [0]
         | https://github.com/git/git/blob/757161efcca150a9a96b312d9e78...
         | 
         | [1] https://github.com/git/git/releases/tag/v2.23.0
         | 
         | [2]
         | https://github.com/git/git/commit/4e43b7ff1ea4b6f16b93a432b6...
        
         | baobun wrote:
         | 5. Teaching `git add .` as default to add changes to the
         | staging area is not ideal. Show adding specific files instead
         | has less room for subsequent "oh shit" and better.
        
           | ajross wrote:
           | True enough, but it _does_ make for good practice with the
           | index and splitting workflows later on when you need to clean
           | it up.
           | 
           | I think there's space for "git add ." as a didactic step. It
           | maps cleanly to the most obvious way to understand a commit,
           | as "here's what I've done". Bootstrapping from that to an
           | understanding of "commits as communication with other
           | developers" will naturally happen over time.
        
             | baobun wrote:
             | Is not very compatible with printlog-debugging. I'd rather
             | encourage devs to prod around as they go if it benefits
             | them, which causes grief for either them or reviewers in
             | the end if they've internalized what you just said.
             | 
             | Explicitly adding internalizes a personal review process as
             | inherent part of the push process, instead of something you
             | attempt to force on top later.
             | 
             | It's better with a collaboration workflow that limits the
             | span of time with expected discipline, imo.
        
               | recursive wrote:
               | You can have both. Make sure the whole diff is what you
               | want it to be before invoking `add .`
        
               | baobun wrote:
               | Sure. I hear the pull-out method is also an effective
               | contraceptive.
        
           | zahlman wrote:
           | Learning about the `-p` option for `git add` was one of two
           | things that revolutionized my Git usage. (The other was
           | figuring out how to write effective commit messages.)
        
             | wodenokoto wrote:
             | This is the main reason to use a GUI imho.
        
               | baobun wrote:
               | Tig is a great one for the terminal fwiw.
               | 
               | gitg for something simple, graphical and widely
               | available.
        
         | jaapz wrote:
         | Could you motivate why you suggest these? Why is `switch`
         | better than `checkout`? And why not use `reset --hard`?
        
           | jopicornell wrote:
           | Not comment OP, but checkout has two very different uses
           | merged into one: restoring files and switching branches. To
           | not break compatibility, git has now switch and restore
           | commands that make commands more readable and understandable.
           | 
           | You should avoid reset --hard because it will delete all your
           | uncommited, and you could end up in situations where that's
           | really bad. Using reset --keep will keep uncommited changes,
           | and failing if any uncommited change cannot be kept.
        
             | teaearlgraycold wrote:
             | I just do                   git add -A              git
             | stash              git reset --hard              git stash
             | pop
        
         | stouset wrote:
         | Rewriting these for jj users. I'm prefering long option names
         | and full command names for clarity here, but all the commands
         | have shortened aliases and all the option names have single-
         | letter alternatives. `@` means "the current revision", `x+`
         | means "the revision just after `x`", `x-` means "the revision
         | just before `x`".
         | 
         | 2. "Accidentally committed something to master that should have
         | been on a brand new branch".
         | 
         | This doesn't really have an analogue. Branches ("bookmarks")
         | only move when you tell them to. If you make a new commit on
         | top of master, it doesn't point master to it, it just lives one
         | past the tip of master. But let's say you accidentally moved
         | master to include the new commit you shouldn't have:
         | # set master to the previous commit (and reaffirm that
         | # you're okay moving a bookmark backward)         $ jj bookmark
         | set master --allow-backwards --revision @-               #
         | there is no step two, you're still editing the change you
         | already were
         | 
         | 3. Move a commit from one branch to another.
         | # move the revision one-past-master on to our desired bookmark
         | $ jj rebase --revision master+ --destination name-of-the-
         | correct-bookmark              # there is also no step two;
         | technically we're not updating the bookmark         # to point
         | to the new commit yet, but this isn't something you'd do as
         | rote         # habit in jujutsu anyway
         | 
         | 4. Fuck this noise, I give up:                   # list all the
         | operations I've performed against the repo         $ jj op log
         | # restore to some previous known-good state         $ jj op
         | restore {id}
         | 
         | Bonus content, translated from the article:
         | 
         | > Oh shit, I committed and immediately realized I need to make
         | one small change!                   # move the current edits
         | into the previous revision         $ jj squash
         | 
         | > Oh shit, I need to change the message on my last commit!
         | # re-describe the previous revision         $ jj describe
         | --revision @-
         | 
         | > Oh shit, I tried to run a diff but nothing happened?!
         | # there is no staging area, all your changes are part of the
         | repo and there is no         # staging area pseudo-commit;
         | please understand that this still works elegantly         #
         | with "patch-add" workflows and does not imply that large change
         | sets can't be         # easily broken up into small commits
         | 
         | > Oh shit, I need to undo a commit from like 5 commits ago!
         | # find the commit         $ jj log              # back it out
         | $ jj backout {id}
         | 
         | > Oh shit, I need to undo my changes to a file!
         | # find the commit         $ jj log              # restore the
         | paths provided to their contents in the given revision
         | $ jj restore --from {id} [paths...]
         | 
         | And finally there are a few things that are super easy/obvious
         | in jujutsu that are far more annoying in git.
         | 
         | > Oh shit, I committed and many commits later realized I need
         | to make one small change!                   # moves the changes
         | in the current working copy into the revision provided
         | $ jj squash --into {id}
         | 
         | > Oh shit, I committed and many commits later realized I need
         | to make extensive changes!                   # sets your
         | working copy to the commit provided; later commits will be
         | # auto-rebased on top live as you make modifications         $
         | jj edit {id}
         | 
         | > Oh shit, I need to reorder two commits!                   #
         | does what it says on the tin         $ jj rebase --revision {a}
         | --insert-before {b}
         | 
         | > Oh shit, I haven't committed anything in hours but I need
         | something from an interim change from like thirty minutes ago
         | # look in the "obsolete log" for earlier iterations of the
         | current revision         $ jj obslog              # restore the
         | contents         $ jj restore --from {id} [paths...]
         | 
         | > Oh shit, I made a bunch of changes but want them to be in
         | multiple commits (e.g., patch-add workflow)                   #
         | choose the parts to move out; you'll end up with two revisions,
         | one with each half         $ jj split
         | 
         | > Oh shit, I need to break out a change from my current work
         | into a new branch off master                   # choose the
         | parts to move out; you'll end up with two revisions, one with
         | each half         $ jj split              # move the stuff I
         | pulled out onto master         $ jj rebase --revision @-
         | --destination master              # optional: name it; most of
         | the time you wouldn't bother         $ jj bookmark create new-
         | name --revision master+
         | 
         | > Oh shit, I need to make three sequential changes but roll
         | them out one-by-one. I also might need to make fixes to
         | previous ones before later ones are rolled out.
         | # author a new change on top of master and name it a         $
         | jj new master         ...         $ jj bookmark create a
         | # author a new change on top of a and name it b         $ jj
         | new         ...         $ jj bookmark create b              #
         | author a new change on top of b and name it c         $ jj new
         | ...         $ jj bookmark create c              # edit a;
         | nothing else is necessary to ensure b and c remain as
         | descendants of         # revision a         jj edit a
         | ...              # author a new change as part of b; nothing
         | else is necessary to ensure c remains         # up to date on
         | top of b         $ jj new --insert-before c         ...
         | # point c at the new change         $ jj bookmark set b
        
           | amanwithnoplan wrote:
           | Please kindly write one for a jj-specific issue: "my build
           | vomitted out a bunch of files and I used any jj command
           | before editing my .gitignore"
           | 
           | I've found myself using git to fix the mess in this
           | particular instance.
        
             | stouset wrote:
             | $ jj file untrack {paths-or-pattern}
             | 
             | Alternatively if you have a bunch of files spewed
             | everywhere with no rhyme or reason which can't be globbed
             | or enumerated reasonably:                   $ jj status |
             | grep '^A' | awk '{print $2}' | xargs jj file untrack
        
           | hooper wrote:
           | One thing I really appreciate is that you can run `jj new
           | master` at _any_ time to drop what you're doing and start a
           | new change. The way jj handles the working copy, conflicts,
           | and visible heads means there's just no need to think about
           | uncommitted changes, unfinished conflict resolution, detached
           | head, etc.. So many things that would get in your way just
           | can't happen.
        
             | stouset wrote:
             | I haven't thought about it at all but you're right. It's
             | surprising how _nice_ it is that I can enter a repo and `jj
             | new main` without needing to remember any context
             | whatsoever.
             | 
             | My post was a pretty naked attempt to showcase how much
             | less convoluted basic operations are in jj vs. git and
             | hopefully drum up some interest. Hopefully someone bites.
        
               | steveklabnik wrote:
               | `jj new trunk()` is even better than `jj new main`, I
               | just realized, ha!
        
               | stouset wrote:
               | It is! I've fully migrated my repos over to `main` at
               | this point so it's rare I have to think about the
               | difference. You could also make an alias to `jj n` or
               | something to make it even easier.
        
         | dustingetz wrote:
         | millennial boomer here where is the gen z cheat sheet for this
         | git switch thing that i keep hearing about
        
         | ajross wrote:
         | > 1. Always use `git switch` instead of `git checkout`
         | 
         | Even harder: always use "git reset --hard".
         | 
         | Basically don't use local branches. The correct workflow for
         | almost every task these days is "all branches are remote".
         | Fetch from remotes. Reset to whatever remote branch you want to
         | work above. Do your work. Push back to a remote branch (usually
         | a pull request branch in common usage) when you're done.
         | 
         | If you need to manage local state, do it manually with tags (or
         | stash, but IMHO I never remember what I stashed and will always
         | make a dummy commit and tag it).
         | 
         | Don't ever try to manually manage a branch locally unless you
         | (1) absolutely have to and (2) absolutely know what you're
         | doing. And even then, don't, just use a hosted upstream like
         | github or whatever.
        
           | smrq wrote:
           | This sounds like the correct Git workflow if you think the
           | correct VCS to use is SVN.
        
             | ajross wrote:
             | And that sounds like you failed to understand me. I didn't
             | say "don't use branches". I said "all branches are remote".
             | Pushing to a branch is communication with other human
             | beings. Mixing your own private state into that is
             | confusing and needless in 99% of situations (and the
             | remaining 1% is isomorphic to "you're a maintainer curating
             | branches for pushing to other people at a well-known
             | location").
             | 
             | All branches are public.
        
               | ryandrake wrote:
               | I have quite a few projects that do not have a "remote"
               | and will probably never have a remote repo. Should I not
               | be using branches at all?
        
               | simoncion wrote:
               | > All branches are public.
               | 
               | What actual problem does this solve? For me, WIP branches
               | only ever get pushed up if at least one of two things are
               | true about them:
               | 
               | 1) They're actually worth preserving, and not some
               | experimental garbage that ended up being totally
               | pointless.
               | 
               | 2) I need to get them off of my local machine for
               | disaster-recovery purposes.
               | 
               | > If you need to manage local state, do it manually with
               | tags (or stash, but IMHO I never remember what I stashed
               | and will always make a dummy commit and tag it).
               | 
               | I don't see the benefit one gets from putting work that's
               | not fit for publication in a dummy commit on a public
               | branch. That's just _asking_ for garbage that noone
               | should concern themselves with to accidentally get pushed
               | up at the end of a long-ass day.
        
               | ajross wrote:
               | > 1) They're actually worth preserving, and not some
               | experimental garbage that ended up being totally
               | pointless.
               | 
               | That seems naive. You don't know what's pointless for
               | _years_ , usually. Can I tell you how many times I've
               | gone back to stale pull requests and topic branches to
               | recover "How did I do this?" code?
               | 
               | > 2) I need to get them off of my local machine for
               | disaster-recovery purposes.
               | 
               | That's called a "backup", and yes, data robustness is a
               | big advantage of this workflow. You're acting like this
               | is some kind of rare event. I push my local work to a
               | branch (or three) on github every hour!
               | 
               | A corrolary is hardware independence, btw. Working off
               | remote branches means I can also stand up a replacement
               | development environment with a simple clone. (And the
               | corrolary to _that_ means that I can trivially document
               | this such that _other_ people can stand up development
               | environments for my stuff, too!)
        
           | snafferty wrote:
           | This is a workflow I've never seen on any team or project
           | I've worked on. Another commenter already mentioned the
           | remote branch for everything preference, but usage of tags is
           | especially interesting to me. I think that's how most people
           | use branches, and tags tend to be more permanent. What do you
           | do when you come back to the commit with the tag, cherry pick
           | it over and delete the tag? It sounds like an overly
           | complicated process compared to having a branch and rebasing
           | onto the current branch when you finally go to make the
           | change for real.
        
             | ajross wrote:
             | Local branches aren't names for anything other humans
             | beings care about. All "branches" discussed in a team are
             | remote. But because branches have "history" and "state",
             | keeping your local names around is just inviting them to
             | get out of sync with identically or similarly-named
             | branches out there in the rest of the world.
             | 
             | > It sounds like an overly complicated process compared to
             | having a branch and rebasing onto the current branch when
             | you finally go to make the change for real.
             | 
             | Not sure I understand the problem here? The rebase is the
             | hard part. It doesn't help you to have a name for the code
             | you're coming "from". If it collides it collides and you
             | have to resolve it.
             | 
             | What I said about tags was just as short term memory "This
             | commit right here worked on this date", stored in a way
             | that (unless I delete or force-update the tag) I can't
             | forget or pollute. Branches don't have that property. And
             | again _local_ branches don 't have any advantages.
        
           | krick wrote:
           | At first I was put aback by this, but it actually kinda makes
           | sense. I mean, if people are giving off unwarranted advises
           | about "the right way" here, yeah, you _should_ start with a
           | remote branch, and push all your work ASAP. Especially when
           | you are closing the lid of your laptop to change location.
           | 
           | ...Not that I am gonna follow that advice, of course. Same as
           | I 'm not gonna use git switch for a task git checkout does
           | perfectly well.
        
         | johnisgood wrote:
         | What do you mean avoid "reset --hard"? Why or why is it not
         | enough in practice? I use it quite often, along with "alias
         | git-restore-file='git restore --source=HEAD --'". It seems to
         | work.
        
         | Am4TIfIsER0ppos wrote:
         | git switch is too new and its man page says "THIS COMMAND IS
         | EXPERIMENTAL. THE BEHAVIOR MAY CHANGE."
        
         | xk3 wrote:
         | > 2. Avoid `reset --hard` at all costs
         | 
         | Sounds like you might be looking for `git reset --keep`
        
       | behnamoh wrote:
       | Git is one of those technologies that I never got to wrap my head
       | around of, because in so many ways it doesn't follow intuition
       | and unless you have been using it for a long time, for literally
       | every action you would probably have to Google or use the man
       | page of the command.
        
         | nomel wrote:
         | I was trying to delete a file from history yesterday.
         | 
         | The built in way (filter-branch) pops up a warning, with a long
         | delay, saying you should hit Control+C and go download a third
         | party python script called filter-repo...
        
           | PaulDavisThe1st wrote:
           | Possibly consider that "deleting a file from history" is
           | rather far outside the norm or recommended practice for git
           | (even though it is, of course, entirely possible)
        
             | nomel wrote:
             | > even though it is, of course, entirely possible
             | 
             | I take the more realistic perspective: until git makes it
             | impossible to commit something that shouldn't have been,
             | like a secret, then deleting a file from history is a
             | fundamental requirement of git.
        
               | tom_ wrote:
               | The designers of git clearly disagreed, as you can guess
               | from its design, so it's not surprising it might feel
               | like a bit of an uphill struggle (and will probably
               | remain so). There are other tools available.
        
               | lcnPylGDnU4H9OF wrote:
               | Even if you purge the history, the secret is compromised
               | and you should stop using it. It's moot whether or not
               | you're able to remove it from history.
        
               | nomel wrote:
               | That's, for secrets. Secrets aren't the only thing one
               | might want to remove retroactively.
        
         | bitwize wrote:
         | It's ok mate. Hackernews says we should be using jj to manage
         | our rewritten-in-Rust code.
        
           | behnamoh wrote:
           | Haha, I'm so glad I didn't fall for the whole rust thing.
        
             | stouset wrote:
             | Both you and GP, please aim higher for comments on HN.
        
           | iimblack wrote:
           | Since you brought it up, I personally switched to jujutsu and
           | prefer it greatly. I regularly help coworkers deal with
           | issues in git and keep dropping hints like `in jujutsu this
           | would've been done way easier like this!`. Nobody bites yet
           | since I think most of them don't want to use the CLI but
           | maybe someday if enough people keep talking about it the
           | inertia will get to the point that we can get some really
           | slick GUIs for jj.
        
         | dmd wrote:
         | As everyone knows, though, Git gets easier once you understand
         | branches are homeomorphic endofunctors mapping submanifolds of
         | a Hilbert space.
        
           | wbl wrote:
           | That's the Darcs joke and you told it somewhat incorrectly.
        
           | behnamoh wrote:
           | Oh geez now that clarifies everything, how could I miss that?
        
           | jimbokun wrote:
           | > homeomorphic endofunctors mapping submanifolds of a Hilbert
           | space
           | 
           | Has to be easier to understand that then all the arbitrary
           | git commands.
        
             | sampo wrote:
             | Git commands, while they may be cryptic, actually mean
             | something. Whereas that was just gibberish made by putting
             | random mathematical words together.
             | 
             | (There is a similar sounding joke about category theory, "A
             | monad is just a monoid in the category of endofunctors" but
             | this sentence has a mathematical meaning.)
        
           | riwsky wrote:
           | Unless you're in a detached HEAD, in which case it's
           | xylomorphic to the left-aligned Galois group of R^3.
        
         | stephen_g wrote:
         | Did you start with Git or have you used other VCS systems
         | before? I started with SVN and then coming to Git, there were
         | obviously things to learn about how it was different but
         | honestly it felt to me like it made things easier in many ways
         | (since I'd experienced the horror of a very large codebase in
         | SVN with lots of branches, and trying to track those and merge
         | back together - git is so much better at that, it's crazy)...
         | 
         | I can see how it would be a much bigger learning curve if
         | people come straight to git, but it's still hard for me to
         | understand where the blocker is that so many people complain
         | about using it...
        
       | antithesis-nl wrote:
       | Yeah, please don't create sites like this. Just... don't.
       | 
       | Any, and I mean _any_ "in case of a Git problem, just do _this_ "
       | recipe is _wrong_ , often in very subtle ways. So, my advice: in
       | case of a Git problem, contact the help channel provided by the
       | organization hosting your Git repository. They'll help you out!
       | And if it's your personal-I-am-truly-the-only-human-using-this
       | repository? Just recreate it, and save yourself the pain.
       | 
       | Source: I'm part of the team behind the #githelp channel in many
       | $DAYJOBs, and _we know_ how hard things are. You committed an
       | unencrypted password file, or worse, your entire  'secret' MP4
       | collection to our monorepo? Sure, just let us know! Pushed your
       | experimental branch to master/main/head/whatever? We'll fix it!
       | 
       | Just don't _ever_ , for whatever reason, run that-chain-of-
       | commands you found on the Internet, without understanding what
       | they do! In most cases, your _initial_ mistake can be undone
       | pretty quickly (despite requiring nonstandard tooling), but once
       | you 're three levels deep and four days later, not so much...
        
         | 1over137 wrote:
         | We're not all working at $bigcorp with dedicated help teams.
         | Sites like this are great and have helped me many times!
        
           | doubled112 wrote:
           | What happens when you are the help team and it's the first
           | time something goes wrong?
        
             | antithesis-nl wrote:
             | A 'team', by definition, consists of more people than
             | 'you.'
             | 
             | And, by the time a '#githelp team' is formed, it's to
             | address patterns to which there are known solutions.
             | 
             | One of the many problems with Git, is that these solutions
             | depend _very, very much_ on the structure of the repo and
             | the common practices of its users.
             | 
             | So, instead of executing random commands from the Internet,
             | just ask. Please! Or, if there's truly nobody going to be
             | around, give in and recreate the repo. You'll save yourself
             | so much pain in the long run...
        
               | recursive wrote:
               | > A 'team', by definition, consists of more people than
               | 'you.'
               | 
               | I'm the resident git expert, but not by choice. There's
               | more that I don't know than that I do. It's not uncommon
               | that I need to use internet recipes to un-wedge someone's
               | clone.
               | 
               | > Or, if there's truly nobody going to be around, give in
               | and recreate the repo. You'll save yourself so much pain
               | in the long run...
               | 
               | This is insane. There are a dozen other people using the
               | remote, not to mention a whole CI/CD build configuration.
        
           | antithesis-nl wrote:
           | OK, so you've truly screwed up your your personal/small-team
           | repos to the point of requiring poorly-understood command
           | sequences from the Notoriously Reliable Internet more than
           | once?
           | 
           | I applaud you for your honesty, but... Really?
        
             | jazzyjackson wrote:
             | Bro, really, self-taught people with a bare minimum
             | understanding of the tools they use are super normal, and
             | when they get into a pit they have to fix it themselves.
             | 
             | Although to your point folks would be better served
             | carefully reading the docs / git book than googling a
             | specific solution to their specific error code.
        
               | antithesis-nl wrote:
               | > Bro
               | 
               | Really?
        
               | jazzyjackson wrote:
               | I guess we're coming from different places. In my
               | vernacular, ending a comment with "...really?" is about
               | as casual as calling somebody bro.
               | 
               | It's gender neutral btw.
        
               | leptons wrote:
               | "Bro" is the furthest thing from "gender neutral". Not
               | sure how you could think it's gender neutral. It
               | originated from male behavior and is definitely not
               | gender neutral. You can address women as "bro" and they
               | might even respond to you but they'll think you're
               | absolutely weird.
        
               | jazzyjackson wrote:
               | "bro", "bruh", it's more of an exclamation of surprise
               | than a title conferred to the person being addressed, but
               | even then, I don't know, people call folks "auntie" and
               | "uncle" who aren't actually their auntie and uncle.
               | language is flexible. it may reference the kind of
               | fraternity between brothers but that feeling is not
               | limited to the male sex.
        
               | kstrauser wrote:
               | Can confirm. It sounds so weird to me, but I hear my kids
               | and their friends call each other "bro" or "bruh" all the
               | time, regardless of gender.
        
               | guenthert wrote:
               | Isn't this like 'guys' including gals a generation
               | earlier?
        
               | DangitBobby wrote:
               | No, the female and non-binary people in my life both give
               | and accept "bro" or "bruh" without complaint. I once
               | asked one of my non-binary friends directly how they felt
               | about "bro", "dude", etc and they consider those words to
               | be gender neutral. They are like the word "man" now ("IDK
               | man").
        
               | Terr_ wrote:
               | > They are like the word "man" now ("IDK man").
               | 
               | That's actually how it was originally, because in Old
               | English "man" just meant a gender-neutral "person."
               | 
               | Gendered versions were "wer" and "wif", so you could have
               | a "wer-man" and a "wif-man", the latter changing
               | pronunciation to become "woman". I suppose this also
               | means that there are both "werewolves" and "wifwolves".
        
               | spokaneplumb wrote:
               | I'm about 95% sure that if I ask my two school-age
               | daughters if it's weird to address girls and women as
               | "bro" or "bruh" in informal circumstances, they'll say
               | no. Since I hear them do it with some regularity.
        
               | syndicatedjelly wrote:
               | U r
        
               | kstrauser wrote:
               | For me, the value of things like this is in learning the
               | terminology for what I broke and how to fix it. I'm not
               | going to copy-and-paste advice off the Internet. I never
               | have. It's still super helpful to see "oh, that thing I
               | want to do is called frobnitzing the corple. Now I know
               | what to Google!"
        
             | recursive wrote:
             | Yes. I think the ratio of small-team repos this describes
             | is close to 100%. You seem to have a certain idea of how
             | repos are managed. I don't think it's very representative
             | of reality.
        
             | zahlman wrote:
             | I don't understand your surprise or disbelief. I would
             | imagine _most_ devs have been there. As evidence: just look
             | at Stack Overflow, and compare it to what it 's apparently
             | intended to look like and how it's supposed to work (as a
             | denizen of meta.stackoverflow.com I am quite familiar with
             | this struggle).
        
         | PaulDavisThe1st wrote:
         | I've been using git for at least 6 years now, maybe 10.
         | 
         | Sites like this are a great aid to remembering how to deal with
         | certain situations. And yes, I understand what the commands do,
         | but that doesn't mean I always could, or always want to, put
         | together the series of steps from scratch.
         | 
         | And also, we self-host our own gitea hosting because we're not
         | getting sucked down by yet another hosting debacle (old enough
         | to have suffered under sourceforge, and don't plan on getting
         | in the same situation again). For git hosting just as much as
         | everything else on line, if you're not paying for it, you're
         | not the customer.
        
           | antithesis-nl wrote:
           | > For git hosting just as much as everything else on line, if
           | you're not paying for it, you're not the customer.
           | 
           | Yeah, lovely trope, but I'm literally talking about
           | organizations hosting their Git repos on a file share here.
        
             | PaulDavisThe1st wrote:
             | Why would you ask employees of a file hosting service about
             | how to use git?
        
         | jpeloquin wrote:
         | Recipes like these aren't useless, but yes, they really need to
         | be prefixed with whether they expect to start from a clean work
         | tree and empty staging area. Or describe what they'll do to
         | uncommitted changes, both staged & unstaged. Otherwise they
         | pose a substantial risk of making the problem worse.
        
         | conkeisterdoor wrote:
         | > "... or worse, your entire 'secret' MP4 collection to our
         | monorepo?"
         | 
         | Oh no, that poor soul...
        
       | divbzero wrote:
       | Previous discussions:
       | 
       |  _Oh Shit, Git_ - https://news.ycombinator.com/item?id=31874308 -
       | June 2022 (232 comments)
       | 
       |  _Oh Shit Git?_ - https://news.ycombinator.com/item?id=24173238 -
       | Aug 2020 (156 comments)
       | 
       |  _Oh shit, git (2016)_ -
       | https://news.ycombinator.com/item?id=19906972 - May 2019 (277
       | comments)
       | 
       |  _Oh shit, git: Getting myself out of bad situations_ -
       | https://news.ycombinator.com/item?id=15951825 - Dec 2017 (509
       | comments)
        
       | Rooster61 wrote:
       | Unable to access this. Might be hugged to death
        
         | tonymet wrote:
         | https://archive.is/qXlY7
        
       | Retr0id wrote:
       | my main use case for LLMs these days is asking it how to (un)do
       | things with git
        
       | tantalor wrote:
       | I'm not a git user, but stuff like this really drives home the
       | idea that "git commit" is meaningless, the only thing that
       | matters is when your commits are pushed or merged.
       | 
       | It's like saving a textfile. Do you write a little message every
       | time you save a file? No that's silly. Just move on.
        
         | trashburger wrote:
         | If I'm saving changes that were done because of a arduous
         | debugging journey and other people are likely to have to refer
         | back to it, yes. In fact, forget little; the smaller the change
         | is, the bigger the text. Some of my changes have 2-3 paragraphs
         | for a 2-3 line change because of the impact.
        
           | kstrauser wrote:
           | Same here. If it took me a week to figure out why to tweak a
           | couple lines of code, I'm going to be explaining it.
           | 
           | (Although also/mainly in the comments if it's something I
           | worry someone might accidentally change back later.)
        
         | shuntress wrote:
         | Well, it is all local until you push so you can do whatever you
         | want.
         | 
         | With that said, it obviously is not meaningless at a technical
         | level because without the commit there is nothing to push or
         | merge. On top of that, at a non-technical level it can be
         | extremely helpful to record some plain-english prose to
         | describe why you are changing something. If you find yourself
         | doing that too often you need to narrow your definition of what
         | constitutes a "change" and/or be more discerning about what you
         | work on simultaneously.
         | 
         | Out of curiosity, if you do not use git, what do you use for
         | version control and change-management?
        
         | globular-toast wrote:
         | Commit is what causes git to make a copy of the file(s)
         | internally. It's vitally important. But there is no point
         | typing in silly messages like "more fixes" etc. What I do is
         | make an initial commit with something like "(WIP) too feature",
         | then keep doing amend commits until I'm happy, at which point I
         | remove the "(WIP)" from the message.
        
         | julianeon wrote:
         | I actually use git for my todolist/diary and I have an alias
         | for when I want to save which does git commit -m "whatever."
         | Basically I do that so I can view the updated version in the
         | mobile app.
        
         | Vampiero wrote:
         | It seems painfully obvious to me that local and remote commits
         | serve different purposes. Local commits are a way to create
         | checkpoints when everything compiles and works and you can move
         | on to the next step. That way you can stash your changes and go
         | back to a working state when you screw things up. Then, before
         | you push those changes, you reset them and split them into
         | proper commits. That way the history is all nice and clean on
         | the remote and it's not just a bunch of "wip"s.
         | 
         | Or you can just squash-merge your PRs and reap both benefits.
        
           | Nullabillity wrote:
           | Even better, `git merge --no-ff` your PRs and use `git log
           | --first-parent` for the simplified "as-if-it-was-squashed"
           | history.
        
           | MetaWhirledPeas wrote:
           | I think people would generally have an easier time with git
           | if they didn't try to fix their commit histories and instead
           | just let their past mistakes be known. If you make a bad
           | commit in git the best solution is to follow it up with a
           | good one that fixes the problem. Squash commits on PRs help
           | too.
        
           | nejsjsjsbsb wrote:
           | I have no pride. I push my dumb commits that chronical my
           | weird journey full of sub-junior mistakes to get to the final
           | state.
        
         | zahlman wrote:
         | >It's like saving a textfile. Do you write a little message
         | every time you save a file? No that's silly. Just move on.
         | 
         | Do you write a little message about your day every time you go
         | to sleep?
         | 
         | I actually don't, and maybe you don't, but plenty of people do.
         | 
         | I think of the Git revision log as much like that sort of
         | diary, offering the same sorts of advantages. It's more
         | organized than having a separate TODO list document; and it
         | encourages you to describe what you've already done in a clear
         | readable way, too. When you're trying to figure out how far to
         | roll back, it may be useful to understand what you were
         | thinking at the time of the commit. And if something turned out
         | to be the wrong approach, it helps you do the post-mortem.
         | 
         | And, of course: if your unmerged, unpushed work is organized
         | into separate changes that have separate (and labelled goals),
         | and part of that work turns out to be good and part bad, it
         | becomes vastly easier to preserve the good parts.
        
       | tonymet wrote:
       | github's "reflog" is the activity log API
       | https://docs.github.com/en/rest/activity?apiVersion=2022-11-...
       | 
       | Useful in case someone force-pushes and no one has the good ref
       | locally.
        
       | SebastianKra wrote:
       | We should start recommending UIs as the default way to learn Git.
       | It would solve a third of these problems and another third
       | wouldn't even come up.
       | 
       | If you later decide that the CLI is faster, go ahead. But first,
       | people need to _see visually_ how they can interact with the
       | tree.
       | 
       | I like fork.dev, but most clients are pretty similar at this
       | point.
        
         | nuancebydefault wrote:
         | The cli is faster if you know by heart but a real disadvantage
         | is that it is hard to "see" what you did or what happened in
         | the past. Good look finding where/whether an old branch got
         | merged and find out if it is part of a release, using cli.
        
           | harrall wrote:
           | Is this really true? When I want to reorder commits, I just
           | drag & drop in a GUI and I'm done. Or if I want to switch
           | branch or manage a complex mix of rebases or cherry picks,
           | it's just 2 or 3 clicks. In CLI, by the time I've typed out
           | the commit hash or locator, it's already taken longer. And I
           | type 130 words per minute.
        
             | dijksterhuis wrote:
             | > by the time I've typed out the commit hash
             | 
             | i don't think i've typed out a full hash in ... years? if i
             | have i've used the short 8 character hash.
             | 
             | git rev-parse might be something useful to have a look at,
             | especially when combined with aliases.
        
               | harrall wrote:
               | Nah I'm talking about the short hash.
               | 
               | But I still have to find the short hash too, and then
               | copy or re-type it... With a UI, I just... click click
               | click done.
        
         | globular-toast wrote:
         | As a magit user I agree, apart from the fact most GUIs I've
         | seen are horrendously broken and can lead to an even worse
         | mess. For example, I was really confused about how a colleague
         | messing up and got them to show me. Turns out in VS Code if you
         | set the upstream branch correctly (ie. to master), it tries to
         | get you to "sync" the branch. So it assumes the upstream branch
         | is the branch you push to, which makes no sense at all.
        
         | koito17 wrote:
         | Agreed that UIs generally provide a better UX for Git.
         | 
         | I use Magit and doing things like "abort cherry-pick" is
         | _discoverable_ in the interface itself and uses the exact same
         | shortcut as the other  "abort X" operations. If I had to use
         | the Git CLI, I'd have no idea where to start.
         | 
         | Similarly, I've made mistakes in interactive rebases where I
         | deleted a commit that shouldn't have been deleted. If I recall
         | correctly, the start of every rebase creates a snapshot that is
         | accessible from the reflog, so this is a safe way to revert
         | changes from a rebase gone wrong. Magit's UI for the reflog is
         | exactly the same as the UI for the log, so I was not lost when
         | I saw it for the first time. With the Git CLI, I'd likely have
         | no clue what's going on.
        
         | JTyQZSnP3cQGa8B wrote:
         | I agree, I have used git for more than 10 years and it's the
         | only tool that I refuse to learn. The command-line interface is
         | cryptic and infuriating. I'd rather write assembly language
         | again than learn what is essentially a CLI to the internals of
         | git. It's not high-level, it's not intuitive, and it can be
         | destructive if you don't use the right option. I stick to GUIs
         | and simple actions, and I never had any problems compared to
         | all the horror stories of my CLI-loving coworkers.
        
         | taberiand wrote:
         | I advocate this with every newbie to git - find a UI that works
         | for you and use it over the cli. Barely anyone listens though,
         | and then they struggle with the cli and make a mess of their
         | branches and fall out of date with main and are scared of
         | rebasing and have many other issues that are solvable with a
         | drag and drop or similar in a UI. I figure it's a sort of
         | masochism.
        
         | MrJohz wrote:
         | I've started recommending jj as a (git compatible) alternative
         | to git, and one of the things I like about it is that the
         | default action if you run `jj` with no arguments shows the
         | relevant parts of the commit tree and where you are in it. This
         | is a great reorientation tool, because you can see at a glance
         | which commit you're working on right now, the branches and
         | history associated with it, any other active branches in your
         | repository, and for each you can see whether each commit had
         | messages, changes associated with it, etc.
         | 
         | It's really powerful because it gives you precisely that visual
         | layout that shows you what's going on in the repository, and
         | what you're doing right now.
        
         | marssaxman wrote:
         | I have not used such a tool in a long time, and never with git:
         | but my past experience with GUI frontends for version control
         | was that they work fine when everything is working fine, but
         | once you have a mess to clean up, nobody can help you.
         | 
         | It has generally worked better for me to use the same interface
         | everyone else is using, even when that interface is awful,
         | because that eases communication with the rest of the team. It
         | also lets me take advantage of online troubleshooting
         | resources, which all assume you are doing things the normal
         | way.
        
         | FractalHQ wrote:
         | lazygit ! Just needed to throw out a mention because it's an
         | amazing tui for visual orientation, is super fast, and can be
         | used with a mouse and keyboard (or just keyboard) from the
         | terminal. I saw it mentioned on a thread here last year and
         | have preferred it as a fast "oh crap I think I made a mess lets
         | back up" tool over the more complex gui apps I've tried (almost
         | all of them).
        
         | dijksterhuis wrote:
         | disagree, with a caveat.
         | 
         | to summarise: use the desktop apps now, but thou shalt need to
         | learn the CLI.
         | 
         | --
         | 
         | when i've taught absolute development beginners how to use git
         | and how to do PRs i show them both the CLI and GitHub desktop.
         | not every single thing. but i at least show them
         | add/commit/push and creating/checking out branches in the CLI.
         | 
         | why?
         | 
         | 1) this CLI thing is what power users / experienced folks use.
         | this is your long term goal.
         | 
         | 2) oh look, the terminal is typing things out instead of
         | clicking on buttons which have slightly different names (target
         | audience has never seen a terminal)
         | 
         | 3a) some things cannot be unfucked in a desktop app. i don't
         | have to explain what the CLI is to show them how to unfuck it.
         | i might have to remind them. but it's not totally alien to
         | them. they're only seeing the fix for the first time, not the
         | fix _and_ the CLI.
         | 
         | 3b) they might feel more comfortable trying to use the CLI when
         | they've already been shown it before. ideally in tandem with 3a
         | -- "hey i need to do this thing to unfuck it, could you sit
         | with me while i go through to avoid fucking it even more"
         | 
         | 4) maybe they go "screw it, i want the pain because i really
         | want to be a magician at this". it's nice for them to have the
         | _option_ of the easier, simpler path when they're having a bad
         | day with it.
         | 
         | ill always suggest that absolute beginners _use_ the desktop
         | apps because it does reduce early fuck ups. and part of that
         | involves showing them the desktop apps.
         | 
         | but i feel they need to be made aware the desktop apps are not
         | the be end and end all. they can try the CLI a few times if
         | they want. at some point, they will have to use it.
         | 
         | they also need to learn to fuck it up. making mistakes is how
         | human beings _really_ learn.
         | 
         | both making mistakes and demo-ing the CLI early, often and
         | safely; rather than later and rarely; gets people to "magician"
         | level faster in my experience.
         | 
         | essentially, you have more to learn buddy. keep working on it
         | if you want to be one of the magicians in the team. if you
         | don't, that's fine. but at some point you'll need to deal with
         | this CLI thing.
         | 
         | --
         | 
         | > people need to see visually how they can interact with the
         | tree.
         | 
         | i've got a whole diagram thing i draw live showing them how
         | everything is based on commits or a collection of commits,
         | moving the commits around in front of them.
         | 
         | seems to be a better way to cover remotes, branches and
         | eventually PRs than leaving them to work it out with some
         | history visualisation which is usually a bit hard to read.
        
         | Izkata wrote:
         | > But first, people need to _see visually_ how they can
         | interact with the tree.
         | 
         | Interactive tutorial with tree visualization that has helped
         | co-workers: https://learngitbranching.js.org/
        
           | alextingle wrote:
           | Thank you for posting that!
        
         | paulddraper wrote:
         | What the average amount of time until something goes wrong that
         | can't be fixed in the UI?
        
           | sksrbWgbfK wrote:
           | For me, once a year and I have to use the reflog. But using a
           | GUI is so much faster and safer that I won't change.
           | Mercurial and Jujutsu have good command-lines, why can't git
           | do the same?
        
           | OkayPhysicist wrote:
           | In more than one team I've been on over the years, I was the
           | only person with a deep understanding of Git. What I've found
           | as a result of being the "oh shit git" guy is that
           | 
           | 1) all UIs are completely missing at least some of Git CLI's
           | functionality (shoutout to git's most neglected feature, git
           | notes)
           | 
           | 2) all UIs have at least a couple git features so tucked away
           | that you'll only find them if you know to look for them (git
           | checkout -- path > temp_file is a common culprit here, but
           | I've seen UIs that hide git ammend)
           | 
           | 3) the average time for a UI-exclusive user to need my help
           | for one of those two reasons was about a month.
        
         | megak1d wrote:
         | Came here to say the same - fork.dev is awesome.
         | 
         | I used to be a CLI git guy but haven't used it in years now
        
         | qalmakka wrote:
         | GUI git clients are amazing in the hands of expert users, but
         | terrible for any newcomer that has to actually use Git (and
         | it's not like a designer checking out the source once or twice
         | a month).
         | 
         | The gripe I have is that unless you expose people to CLIs early
         | on, they will just not learn how to use a CLI at all. Whenever
         | something inevitably breaks badly due to GUIs abstracting away
         | how git really works in favour of a nicer UX, they'll end up
         | asking someone that know Git how to fix their mess. And then,
         | it's too late - they already know how to be productive-ish with
         | git and how to deliver something. They can't justify investing
         | time into learning the CLI (especially if they're not that
         | great with Powershell or UNIX shells) so they constantly keep
         | leaning on a colleague instead of learning.
         | 
         | This is not an hypothetical scenario - this really happened
         | regularly at a place I worked at. Innumerable internal training
         | lessons on Git went wasted due to people forgetting everything
         | immediately by using Fork instead of the shell, and then
         | pestering a handful of senior devs. Once IT banned Fork people
         | were forced to use the terminal more often, so they had to
         | learn how to use git for good and actually retained that
         | knowledge via muscle memory.
         | 
         | The adage I've learnt over the course of the years is that the
         | majority of people will go to any length to avoid learning new
         | stuff. It's mentally less tiring to either waste their time
         | doing stuff in an unproductive way than learning new things.
         | IMHO it's better to force people to learn stuff the "right way"
         | early on than let them pick up bad habits and then having to
         | correct them later.
        
       | franky47 wrote:
       | One of the beauties of Git is that as long as you've created an
       | object, it's impossible to lose that work (short of nuking the
       | .git directory).
       | 
       | Committing often is key. Precommit hooks (that take more than
       | ~100ms) go against that.
        
         | ge96 wrote:
         | I have had git corruption problems on a raspberry pi sd card,
         | usually I just had to reclone/abandon that folder
        
           | stephen_g wrote:
           | It honestly sounds like git is the least of your problems
           | here...
        
         | extraduder_ire wrote:
         | If you orphan the object by not having anything point to it, it
         | goes away when "git gc" is run. That happens automatically
         | after about two weeks by default.
         | 
         | Even things like "git add" will create objects stored in the
         | .git folder.
        
       | amelius wrote:
       | This is why I run Git inside Git, as the latter allows me to undo
       | anything I do within the former.
        
         | CharlesW wrote:
         | As a Gitginner I'm wondering if this a good joke that went
         | "wooooosh", or if this has something to do with submodules,
         | or...?
        
           | shuntress wrote:
           | Git manages pretty much everything by using the `.git` folder
           | created by `git init` and there is (as far as I am aware)
           | nothing stopping you from going into that .git folder and
           | running init again there to start using git to manage the
           | internal state of your repository. At least... that is what I
           | assumed the joke was.
        
         | deadbunny wrote:
         | Literally `git reflog`
        
       | javier_e06 wrote:
       | Lately I've been asked to avoid merge-commits. They pollute the
       | logs? If my push is blocked I am too far behind I create a new
       | temp branch of master and do a "merge --squash" to it and then a
       | "reset --hard" from temp branch back to my original branch. Heck
       | sometimes I rather keep my changes in patches to void does darn
       | merge CONFLICTS...specially when rebasing.
        
         | a_t48 wrote:
         | From memory...                   git merge origin/master
         | git reset origin/master         git commit -am "squash" # might
         | need some extra fixup if your branch has added files
         | 
         | No need to make a temp branch. I know there's probably a more
         | efficient way of doing this, but this is what's stuck in my
         | head.
        
         | pitaj wrote:
         | Hard to understand exactly what your issue is here. Typically
         | when people say "avoid merge commits" they mean they want you
         | to almost always rebase instead of merge. Can you give an
         | example or something?
        
         | nuancebydefault wrote:
         | The thing is if you merge immediately into master and have
         | conflicts, you solve the conflict and only then you can merge.
         | But then the conflict resolution sits at the merge point with a
         | weird default commit message and is hard to decipher.
         | 
         | A nicer way is merge master into your branch, with the rebase
         | option (you can set that option as the default). This will put
         | your changes on top of the master changes that happened during
         | populating your own branch. There you solve any conflicts and
         | those usually immediately show you what happened in the
         | meantime, making it easier to do so. The latest greatest now
         | sits in your branch.
         | 
         | Then as a plus, you can retest that merge and if necessary, fix
         | the merge.
         | 
         | Optionally you can do a pull request for reviewing. The diff
         | the reviewers see is conflict-less and makes sense, has only
         | your changes.
         | 
         | Then simply merge to master, which should be trivial if you
         | don't wait for long.
        
           | Nullabillity wrote:
           | Merge main into your branch, then merge --no-ff your branch
           | into main. No need to rebase or squash anything.
        
             | Izkata wrote:
             | > Merge main into your branch
             | 
             | The same problem GP was trying to avoid is created here,
             | the merge conflict resolution being on the merge commit.
        
         | WorldMaker wrote:
         | I think that people that think merge commits "pollute the logs"
         | are missing key git features such as `--first-parent`. Git is
         | natively a _graph_. It gets a lot of powers from that. If you
         | don 't want to see all the details of the "subway diagram", add
         | `--first-parent` as a default and focus on the higher level.
         | Merge commits help avoid later conflicts by _saving_ how
         | earlier conflicts were solved. Three-way merging in general and
         | many of git 's more complex merging strategies all work
         | _better_ if you save the merge commits. Rebasing throws that
         | baby of information out with the bath water. (It 's also useful
         | information to have as a developer needing to archeology dive
         | for _how_ a regression happened. With a merge commit you can
         | see the fingerprints of a bad merge or a mistake that wasn 't
         | caught in an ugly merge. With a rebase or squash that
         | information is gone, you have no idea where to find the bad or
         | ugly merges, that data is swept under the rug.)
        
           | Nullabillity wrote:
           | On top of this, integration is an "interesting" step on its
           | own! When trying to diagnose an issue it can be super
           | valuable to be able to understand whether it was broken from
           | the start or broken by the merge. Rebasing throws all of that
           | valuable information away!
        
       | daitangio wrote:
       | I love this site, it helped me and it also funny. Kudos to the
       | creator!
        
       | bitwrangler wrote:
       | Other fun git hacks...
       | 
       | * https://hackaday.com/2017/05/23/stupid-git-tricks/
       | 
       | * https://ongardie.net/blog/sqlite-in-git/
        
       | grokx wrote:
       | I can also recommend git flight rules:
       | https://github.com/k88hudson/git-flight-rules
       | 
       | It saved my work a couple of times.
        
       | mfashby wrote:
       | Related, you can get this as a nice printed zine
       | https://jvns.ca/blog/2018/10/27/new-zine--oh-shit--git-/
        
       | frakt0x90 wrote:
       | I'm not proud of it, but my #1 "Oh shit" git operation is to just
       | delete my local repo, reclone, and reapply the changes. Works
       | really well for me 95% of the time. The rest I ask dev ops guy to
       | help.
        
         | wruza wrote:
         | This should be a built-in                 git unshit
         | 
         | Or                 git add --unshit -f ~HEAD^^
         | 
         | If you're using git version <= 2.844.
        
           | maleldil wrote:
           | Jujutsu has `jj undo`, but which undoes whatever was your
           | last jj command, regardless of what it was. It makes much
           | more confident to do an operation I'm uncertain of. And if I
           | regret something many actions down the line, you have `jj op
           | log` (a better reflog).
        
             | zahlman wrote:
             | If you `jj undo` a second time, does it redo (undoing the
             | undo), or does it back up another step?
        
               | steveklabnik wrote:
               | It redos, there's discussion about if and how this should
               | change: https://github.com/jj-vcs/jj/issues/3700
        
             | blharr wrote:
             | Such a simple operation, but it'd probably fix 95% of
             | problems I've had with git.
             | 
             | "Uh oh, I tried to checkout a branch from remote by doing
             | `git checkout origin/some-branch` instead of `git checkout
             | some-branch` and made a couple source changes. Now I'm in
             | detached head state. What is detached head ? I have to
             | stash my revisions? Can I make a new branch with the same
             | name or do I need to delete the origin/some-branch that I'm
             | on?"
             | 
             | When you could be able to just revert the "operation" and
             | check out the correct branch, that's amazing.
        
         | spokaneplumb wrote:
         | I've been using Git for almost 15 years, and have _twice_ built
         | programs /products that use Git internally to achieve certain
         | results (that is, the program/product itself uses Git for
         | things, not just using Git to manage the source code for the
         | program/product) and... sometimes before doing something a
         | little gnarly in Git I'll still just do "cp -R .git ../git-
         | backup" or something like that, so I can replace my entire .git
         | dir with an older copy if I screw it up too bad. It's a ton
         | faster than figuring out the right way to un-fuck any
         | particular operation or set of operations.
        
           | fragmede wrote:
           | Reflog is your friend.                   git break-my-shit
           | git reflog             ... output saying where you were
           | before things broke             ... grab the good commit sha
           | git reset --hard good_commit_sha_from_reflog
        
             | compiler-guy wrote:
             | And yet up above we have others recommending to never,
             | ever, use `git reset --hard ...`.
        
               | psyclobe wrote:
               | The same people probably want to ban knives!
        
             | spokaneplumb wrote:
             | The copy-the-.git-dir trick works for worse issues than can
             | be solved with a single reset --hard. Damn near anything,
             | really, as long as you haven't touched any remotes. It also
             | works if you don't remember/understand how you broke it,
             | where it's broken, or which state you need to try to reset
             | to.
        
         | guenthert wrote:
         | You're not alone. https://xkcd.com/1597/
        
       | philipwhiuk wrote:
       | My hot take is that Git isn't nearly as hard as the endless blogs
       | pretend.
        
         | reaperducer wrote:
         | Git is a technology that was invented to simplify things that
         | ended up getting so complex over time that an entire industry
         | started up around it to try to make it simple again.
         | 
         | See also: Docker. Probably lots of others.
        
           | globular-toast wrote:
           | Actually, no. Git was a technology invented specifically to
           | enable Linux kernel development. It hasn't become any more
           | complex since its inception. The problem is most people
           | aren't doing kernel development and have absolutely no idea
           | what a distributed version control system is, yet they use
           | git, a distributed version control system. I have no idea why
           | we use it, to be honest, but I'm very glad that we do because
           | the previous options were crap. Perhaps Mercurial is better,
           | but git is good enough.
        
             | adamc wrote:
             | We were using svn before Git and easy cloning (and then
             | PRs) has solved a LOT of problems. There are definitely
             | still some things left to improve, though.
        
         | tester756 wrote:
         | "hard"? it is not hard, it is just poorly designed, the API
         | (commands) are really terrible.
         | 
         | Think of it: one person who cares about UX decades ago could
         | make git 10 times more sane for milions of devs.
        
         | jeppester wrote:
         | I'm happy I didn't have to scroll too far to see this.
         | 
         | Git's CLI isn't elegant, but it really isn't that big of a deal
         | if you understand the basics of what a commit is, what a branch
         | is etc.
         | 
         | I struggle to understand why so many devs decide to treat it
         | like mysterious arcane sorcery instead of just spending the
         | needed time on learning how it works.
         | 
         | The same can be said about regexes.
         | 
         | Regexes and git are probably the two tools which I have
         | benefitted the most from learning compared to how little time
         | I've spend on learning them - and I wouldn't even consider
         | myself an expert on either.
        
           | tester756 wrote:
           | >I struggle to understand why so many devs decide to treat it
           | like mysterious arcane sorcery instead of just spending the
           | needed time on learning how it works.
           | 
           | For example: you have bazilion ways to achieve the same
           | thing, all of them having its own quirks/advantages?
           | 
           | It is just poorly designed, that's it, lol.
           | 
           | I like to joke that if somebody else invented Git, then it'd
           | be 10% less powerful, but 10 times more user-friendly
        
             | stephen_g wrote:
             | But any software evolves over time so if it had fewer ways
             | of doing things in the past, it would very likely
             | eventually pick them up because people have use cases for
             | the advanced features.
             | 
             | It's like complaining about languages ("English is hard to
             | spell and doesn't have consistent pronunciation" etc.),
             | they're constantly changing and that kind of thing is going
             | to happen eventually...
        
           | marssaxman wrote:
           | > it really isn't that big of a deal if you understand the
           | basics of what a commit is, what a branch is etc.
           | 
           | Yes, that's what people mean when they say that git is hard.
           | Instead of presenting you with an interface expressed in
           | terms of the domain you intend to work in, whose commands
           | represent the tasks you intend to perform, git dumps its guts
           | all over the place and requires each user to re-implement the
           | interface between "what you want to do" and "how git is
           | built" inside their own brains instead. Once you have written
           | git's missing user interface in your brain, you are fine; but
           | that's a lot of work which is not necessary with other
           | version-control systems.
        
       | ioncannon wrote:
       | Hey I worked with the person who made this! She did a fun
       | presentation for our company.
        
       | codazoda wrote:
       | Is this related to "Oh Shit, git?" by Julia Evans?
       | 
       | https://wizardzines.com/zines/oh-shit-git/
       | 
       | Perhaps not and the authors just named it the same because it
       | rolls off the tongue nicely.
        
         | jvns wrote:
         | Yes! Katie and I made it into a zine because I was such a huge
         | fan of her work on https://ohshitgit.com/. (you'll notice she's
         | a coauthor of the zine)
        
       | globular-toast wrote:
       | The one thing I wish people would internalise about git is _it 's
       | an append only data store_. To get work into the store, you
       | commit it. Once in the store there is not a command in git that
       | can remove it.
       | 
       | This is how the reflog works. Whatever you do, you can get back
       | to a previous branch state and restore the work from the data
       | store.
       | 
       | But git can't help you if you don't commit. So just commit.
       | Commit all the time. If you think it's too much overhead and you
       | always forget to commit, fix your tools. If you're writing code
       | all day you should be committing at a minimum every hour, in
       | general.
        
       | phtrivier wrote:
       | This will feel very weird in April 2025, when we celebrate the
       | 20th anniversary of git.
       | 
       | I was there. And at some point I wondered if I should learn git,
       | darcs, or bazaar, to replace SVN or CVS. Or did I try mercurial
       | too ?
       | 
       | I wonder if the "GitHub" effect has basically killed the need for
       | a newcomer in the space of VCS. Maybe at some point, the yak is
       | shaved enough ?
        
         | jimbob45 wrote:
         | SVN has always worked for me. You don't have to "teach" people
         | SVN because it's intuitive and works just fine for the 99%
         | case. I wish we would all stop larping as 1337 hackerz and just
         | admit that git is overkill for the vast majority of people.
        
           | dasil003 wrote:
           | svn is perfectly fine and intuitive as long as you never want
           | to branch and merge
        
             | bear8642 wrote:
             | huh?
             | 
             | Svn can branch and merge - maybe bit more clunky but still
             | works
        
           | grandiego wrote:
           | I agree with your sentiment. I was kind of "forced" to use
           | (and eventually fully migrate to) git because the IDE
           | integration to SVN became more quirky every year. Instead,
           | git is already integrated in IDEs these days.
        
           | WorldMaker wrote:
           | Starting a new repo in SVN is find a server somewhere, if
           | doesn't have SVN install SVN, if it does have SVN deal with
           | whatever politics runs its trunk to find space/define a
           | branch structure for you, and so forth.
           | 
           | It is its own footgun as well, but with git you can git init
           | any directory you want and have a repo. Other than the
           | learning curve of the not particularly well tuned CLI (and
           | there are all sorts of graphical clients today and
           | alternative CLI clients), it's very low barrier to entry to
           | get something/anything in source control.
           | 
           | It's not just "larping as leet hackerz", there are real
           | benefits to git over SVN. There are fewer barriers to entry
           | for small teams and hobby devs, especially in a world with
           | GitHub/GitLab/Sourcehut/and more, but also in the world where
           | maybe a git repo never syncs with any other single machine or
           | is hosted on the barest feature set SAMBA folder or is only
           | ever using email-based PR flows.
           | 
           | git could be easier to teach. git could have a better out of
           | the box CLI. That doesn't mean "git is overkill" especially
           | from the point of view of "needing a whole central server
           | setup just to store multiple versions of a file is overkill".
           | Git is perhaps "underkill", it does the bare minimum as best
           | it can in whatever environment you give it. It's
           | intentionally dumb and stupid (hence its name, to be fair)
           | and it's learning curve is as much because it is "too dumb"
           | than because it "isn't intuitive". I've seen some "intuitive"
           | UIs built on top of it. Another comment here remarked "git
           | isn't a source control system, it's a low level toolkit for
           | building your own" and that's not far from the truth and
           | definitely not far from git's origins (and its name). That's
           | a sort of "underkill". ("One day we'll finally build the
           | right, intuitive high level API." That's basically how git
           | was designed. You don't have to just take my word on that,
           | you can search the old mailing lists for all sorts of
           | interesting discussions and debates on "porcelain" options.)
        
             | zahlman wrote:
             | >Starting a new repo in SVN is find a server somewhere, if
             | doesn't have SVN install SVN, if it does have SVN deal with
             | whatever politics runs its trunk to find space/define a
             | branch structure for you, and so forth.
             | 
             | Many years ago, SVN worked fine for me for single-user
             | projects. I just made my own desktop be the server. But I
             | wasn't publishing my code back then (it's not as if I would
             | have have any effective way to tell people about it
             | anyway). Now I have no idea how the equivalent of "pushing
             | to origin" would have worked.
        
               | WorldMaker wrote:
               | Around the period I might have adopted SVN I recall it
               | was a huge pain, if not impossible, to install on a
               | Windows desktop; I tried multiple times, failed at each
               | attempt, and eventually gave up. I was also in some labs
               | at the time where we weren't allowed RDP to personal
               | machines or services, or the lab machines just weren't
               | great at it, or both (depending on the exact type of lab
               | class and how worried the professor was of plagiarism),
               | and mostly only had access to dumb sftp systems during
               | the labs. That's when I discovered and fell in love with
               | darcs. Distributed source control is great. Source
               | control that you can push changes to/from the dumbest
               | file systems is a super power. (Just the other year,
               | even, I was using git and a dumb folder share to move
               | source control changes to and from a VM that was
               | firewalled from any network traffic because it had to
               | be.) I miss some of the smarts of darcs still somewhat
               | regularly having adjusted to this timeline where git won
               | handily, but I'm not going back to a centralized source
               | control system and git is "good enough" most of the time.
        
               | Rexxar wrote:
               | You can create a repo in a directory and use the local
               | path in svn url without using any service or server
               | process since the beginning of SVN.
               | 
               | You can even do it on shared directory for a small team
               | even it's not recommended if there is a lot of concurrent
               | users.
        
               | zahlman wrote:
               | I just used the TortoiseSVN installer on a couple
               | different machines and I recall it being perfectly smooth
               | each time.
        
           | mardifoufs wrote:
           | SVN is more alien to me than git. Does that make you a
           | LARPing epic hacker?
        
           | krick wrote:
           | Working with SVN was terribly slow on any decent size
           | codebase.
        
           | hiAndrewQuinn wrote:
           | Clearly you have never needed code search across 50+ SVN
           | repositories before, then. ;)
           | 
           | No, but seriously, I wrote https://andrew-
           | quinn.me/reposurgeon for a reason. While I actually see some
           | big benefits to SVN over git for areas with large binary
           | assets like game development, the tool is just so ancient
           | these days that it's just easier for me to convert SVN repos
           | to git repos and then use those to figure out what I actually
           | need to do. It feels a lot like working with Laplace
           | transforms, translating and un-translating between two not
           | quite equal ways of measuring reality.
           | 
           | That's not even considering that the kinds of companies still
           | using SVN in 2025 tend to have a lot of code to wade through.
           | Serious selection effects in play there -- mostly for good,
           | to be clear.
        
         | steveklabnik wrote:
         | The GitHub effect is real, like all network effects, but that
         | doesn't mean improvement is impossible. I've switched entirely
         | to jj, and it having git compatibility means that I don't need
         | to rely on anyone else to make that happen.
         | 
         | I am growing increasingly frustrated with various aspects of
         | GitHub, and so I hope someday we all move past it too, but I
         | don't think there's as simple of a path forward there.
        
         | paulddraper wrote:
         | Any improvement will have to be git compatible at the very
         | least, e.g. jj.
        
       | acombandrew wrote:
       | this is good but is extremely reddit
        
       | julienb_sea wrote:
       | Oh shit, I accidentally `git reset HEAD~1` and moved the last
       | commit to file diffs, which was a merge to master, and my file
       | diff now is both the last branch merge and everything I've done
       | in the last 8hrs. I did this once and it was a gigantic PITA to
       | undo, if anyone has any hot tips for that particular idiocy...
        
         | Am4TIfIsER0ppos wrote:
         | `git reset` again to move to the right commit
        
       | bradhe wrote:
       | Love that the very first thing mentions reflog, arguably the most
       | confusing and complicated git feature.
       | 
       | The rest are good though.
        
       | argentinian wrote:
       | I believe I have a good mental model of what git does, but I
       | never remember commands' arguments to use when they are
       | moderately complex. I mean that the commands are not discoverable
       | or easy to memorize.
       | 
       | I don't know if that's because the text UI is bad, or because
       | it's simply difficult to explain with text what to do to
       | manipulate a tree.
        
         | stackghost wrote:
         | Both.
         | 
         | Manipulating complex trees via text is not easy, but the text
         | UI is objectively bad:
         | 
         | https://stevelosh.com/blog/2013/04/git-koans/
        
       | gootz wrote:
       | Pro tip: Sometimes it's easier to rewrite you're entire app
       | rather than wrestle with git commands. /s
        
       | GianFabien wrote:
       | Reading these tips confirms that I'm too stoopid to use git.
       | 
       | Fortunately, I don't have to use git. So I just store work-in-
       | progress as time-stamped files. Storage is cheap and plentiful.
       | Can always diff, cherry pick, etc without confusing myself.
        
       | dgfitz wrote:
       | I'm pumped a search for hg+mercurial had hits in this thread. I
       | am and will continue to be completely blown that hg lost the dvcs
       | wars. It's a better tool.
        
         | gmueckl wrote:
         | It _is_ the unquestioningly better tool right now. It 's
         | available, stable, battle-tested and it's actively supported.
         | It's a case of "being the change you want to see". Just use it.
         | Claims that it lost are counterproductive. The implicit
         | deterrence from those statements is what is actively keeping
         | Mercurial's adoption low.
         | 
         | Hosting is available at least from Sourcehut and heptapod.host.
         | 
         | I'm running a private Heptapod instance (Gitlab fork with
         | direct Mercurial support). It just works.
        
           | greazy wrote:
           | Are there any public forges that support hg?
        
             | gmueckl wrote:
             | Have a look at heptapost.host for paid hosting and
             | foss.heptapod.net for free public hosting for OSS. Is that
             | what you are looking for?
        
             | romaniitedomum wrote:
             | > Are there any public forges that support hg?
             | 
             | Sourceforge, Sourcehut, and GNU Savannah all support
             | Mercurial.
        
         | paulddraper wrote:
         | It's the slower tool.
        
           | guenthert wrote:
           | That was relevant to Linus in the early 2000s, but then, we
           | didn't have NVMe SSDs.
        
         | thatsthejoke wrote:
         | That sounds interesting. Does anyone have a GitHub link?
        
       | jaitaiwan wrote:
       | I swear there used to be a choose your own adventure version of
       | this where you could answer questions about what you did wrong
       | and get a step-by-step "here's what to do" after.
        
         | zargon wrote:
         | Perhaps it was this one?
         | https://sethrobertson.github.io/GitFixUm/fixup.html
        
       | felipeerias wrote:
       | For a developer, one of the most useful things that LLMs can do
       | is help out with Git issues.
       | 
       | It really says something about the design and documentation of a
       | tool when you need a (far more complex and energy-intensive)
       | Artificial Intelligence to be able to use it without making too
       | many mistakes.
        
       | margaretdouglas wrote:
       | I force pushed over origin/master from a very not-up-to-date
       | feature branch and don't have the remote history I overwrote
       | fetched locally.
        
       | sagarpatil wrote:
       | I just use cursor agent to do git now (unless it's simple stuff)
        
       | sundarurfriend wrote:
       | Silly comment, but:
       | 
       | Every time I see `git reflog`, I see it as re-flog. It's possible
       | that's even the reason I never remember the command, I
       | subconsciously can't bring myself to think of it as "reference
       | log". Instead, it's asking git to sell something cheaply,
       | _again_.
        
         | yonatan8070 wrote:
         | I have that with fstab
        
       | kmoser wrote:
       | > Only amend commits that only exist in your local copy or you're
       | gonna have a bad time.
       | 
       | "Gonna have a bad time?" I really wish things like this were
       | explained in more detail, rather than with glib warnings that are
       | unhelpful unless you already know what they mean.
        
         | extraduder_ire wrote:
         | The commit you're amending doesn't exist on your copy anymore,
         | despite existing on the remote that you've pushed to.
         | 
         | Warnings about detaching the HEAD in git are so common that
         | they're kind of assumed to be basic knowledge to a lot of
         | people. Explaining why it's bad if you don't already know would
         | take quite a while too.
         | 
         | I do wish git had some form of warning before you rewrite
         | history that's been pushed somewhere. It should already have
         | all the data to know that.
        
       | upghost wrote:
       | Before learning magit on emacs, this site saved my ass so many
       | times. After learning magit on emacs, this site saved my ass so
       | many times.
        
         | blharr wrote:
         | It used to save my ass a lot. It still does, but it used to,
         | too.
        
       | meinersbur wrote:
       | Avoid `git reset --hard` and `git clean -xfd`. To get a clean
       | working-tree, use `git stash --all`. Allows restoring files if
       | necessary. Saved my sorry bottom multiple times.
        
       | user4511 wrote:
       | Oh how I wish more devs would just read the documentation for the
       | tools they pick. I read the git documentation end-to-end. Never
       | really had any issues with it and most commands feels natural to
       | use.
        
         | blharr wrote:
         | If you memorize the documentation I suppose there's no problem
         | with it, but even then there's confusing things from the
         | beginning design approach.
         | 
         | Like, reset vs revert vs restore, using three similar starting
         | synonyms for different operations.
         | 
         | Reset is particularly confusing because it sounds incredibly
         | destructive, but if you do a soft 'git reset', it just moves
         | the "changes to be committed" to be not staged for the commit.
         | 
         | Then, if you change a single flag (--hard) it is destructive,
         | instead erasing all those changes from your disk.
         | 
         | And there's a reason nobody reads the docs, because they're
         | laid out confusingly at first glance to an unfamiliar person.
         | 
         | If I go to git-scm.com, click docs, the first suggestion is the
         | reference manual. The first guide is on "gitattributes" which
         | gives no philosophy or context as to what it is even used for.
         | Ok, maybe, I'll just check the complete list of git commands...
         | and it starts talking about porcelain and plumbing. Nope, thats
         | not what I need. Maybe try the link "git" under Setup and
         | Config. There the description finally links to a useful
         | "gittutorial" page.
         | 
         | The gittutorial even has some confusing or specific terminology
         | that makes git seem hard. From the beginning of importing a new
         | project "Assume you have a tarball project.tar.gz with your
         | initial work"... why do we need to refer to tar at all, and it
         | doesn't even do the credit of explaining the tar xzf command or
         | what that tarball is. It could easily say 'assume you have a
         | directory', which is the more common case and be 200% more
         | simple.
        
       | scudsworth wrote:
       | 8 years of posting this
        
       ___________________________________________________________________
       (page generated 2025-01-17 23:02 UTC)