Yeah learned this the hard way.

  • Ephera@lemmy.ml
    link
    fedilink
    English
    arrow-up
    137
    ·
    2 days ago

    I’ve had juniors who didn’t believe this, so just to say it: If you know what you’re doing, practically any Git problem is recoverable.

    The one major exception is if you delete your local changes before committing them.

    • sucoiri@lemmy.world
      link
      fedilink
      arrow-up
      3
      ·
      24 hours ago

      Fun fact! If you added a file but never committed it you can still recover it with git fsck --lost-and-found. The changes were still added to the git object store, and by grepping through the dangling blobs you can find the object containing the changes you care about.

    • sorter_plainview@lemmy.today
      link
      fedilink
      arrow-up
      50
      ·
      2 days ago

      Yeah.But many of them are extremely annoying. Specifically screwing up rebase. It is recoverable, but very annoying.

      That said I have seen juniors make two other common mistakes.

      1. Pushing your commit without fetching
      2. Continuing on a branch even after it was merged.

      I’m fed up with these two. Yesterday I had to cherry-pick to solve a combination of these two.

      • psycotica0@lemmy.ca
        link
        fedilink
        arrow-up
        38
        ·
        edit-2
        2 days ago

        Maybe I’m just a wizard, or I don’t know what y’all are talking about, but rebases aren’t special. If you use git reflog it just tells you where you used to be before the rebase. You don’t have to fix anything, git is append only. See where the rebase started in reflog, it’ll say rebase in the log line, then git reset --hard THAT_HASH

        Pushing without fetching should be an error. So either they got the error, didn’t think about it, and then force pushed, or someone taught them to just always force push. In either case the problem is the force part, the tool is built to prevent this by default.

        Continuing after merge should be pretty easy? I’d assume rebase just does it? Unless the merge was a squash merge or rebase merge. Then yeah, slightly annoying, but still mostly git rebase -i and then delete lines look like they were already merged?

        • sorter_plainview@lemmy.today
          link
          fedilink
          arrow-up
          18
          ·
          2 days ago

          See all this is fine for someone with good experience in git. They know how to solve the screw up. But wih junior devs, who don’t know much about it, they will just get confused and stuck. And one of the senior has to involve and help them solve. This is just annoying because these can be avoided very easily. Until they understand the pattern of how everyone operates with git, it just creates issues.

          To me first time causing this issue is completely fine. I will personally sit with them and explain then what went wrong and how to recover. Most of them will repeat it again, act clueless and talk like they are seeing this for the first time in their life. That is the difficult part to me.

          May be I’m just old school, and a grumpy old person, even though I’m not that aged.

          • zalgotext@sh.itjust.works
            link
            fedilink
            arrow-up
            2
            arrow-down
            1
            ·
            1 day ago

            Sounds like the onboarding process needs to have a step in it that says “here’s a link to a git tutorial, read this and get familiar with using git, as it’s an integral tool that you will use every single day on the job”. Bonus points for providing a sample repo that juniors can use to mess around with git, extra bonus points for including steps in the onboarding materials for the juniors to set up their own repos to play around with.

        • Mr. Satan@lemmy.zip
          link
          fedilink
          arrow-up
          4
          ·
          2 days ago

          Same… My usual strategy: rebase, if conflict abort and merge, if no conflict continue; merge always with explicit commits to master / main (no fucking squashing); keep task references in branch names and commit messages.

          • balsoft@lemmy.ml
            link
            fedilink
            arrow-up
            1
            ·
            1 day ago

            Same, but typically I will just resolve the conflicts during the rebase. Makes for cleaner commit history. Merge commits are for combining multiple big unrelated pieces of work together, where rebasing would be too annoying (let’s say 100s of commits each).

            • Mr. Satan@lemmy.zip
              link
              fedilink
              arrow-up
              1
              ·
              edit-2
              1 day ago

              In my cases I has to solve same code conflicts multiple times during a rebase, so I just don’t try them when hit with conflicts.

              I fail to see the benefits of “clean” git history

              • balsoft@lemmy.ml
                link
                fedilink
                arrow-up
                1
                ·
                1 day ago

                In my cases I has to solve same code conflicts multiple times during a rebase, so I just don’t try them when hit with conflicts.

                Yeah if you have two branches, both with a bunch of commits which all modify the same areas of code, and reordering the commits doesn’t help, I can see how it is easier to merge.

                I fail to see the benefits of “clean” git history

                Well, if the commit history is clean and mostly linear, it’s much easier to read, understand and review. git blame will also be much nicer which is really important for debugging big codebases. Of course it’s a tradeoff, as usual.

                • Mr. Satan@lemmy.zip
                  link
                  fedilink
                  arrow-up
                  1
                  ·
                  1 day ago

                  Maybe I just haven’t been exposed to bad examples. Never had any issues with blame and merge commits.

        • Klajan@lemmy.zip
          link
          fedilink
          arrow-up
          2
          ·
          1 day ago

          Continuing on a squash merged branch is very annoying, and I had to deal with this in one repo regularly… Luckily I was annoyed enough to research about this and found out about rebase --onto "main merge commit" "branch merged commit".

      • balsoft@lemmy.ml
        link
        fedilink
        arrow-up
        2
        ·
        edit-2
        1 day ago

        Specifically screwing up rebase. It is recoverable, but very annoying.

        WDYM? Typically git rebase --abort will “just work”. If you have specifically done something really wrong, just look into git reflog and then git reset --hard to whatever commit you were before the rebase.

        Pushing your commit without fetching

        Git won’t allow you to do that if you set up your server properly. It will force you to pull first. I have [pull] rebase = true in my settings so that it always rebases my commits instead of merging them, which makes for much cleaner history.

        Continuing on a branch even after it was merged.

        This generally shouldn’t be a problem, you can just rebase the branch afterwards and it will be fine (the common commits will typically just be dropped).

        • sorter_plainview@lemmy.today
          link
          fedilink
          arrow-up
          1
          ·
          1 day ago

          The problem is not when I have to rebase. I know how to handle it. But with juniors they approach us only when things are in a really bad situation, where they cluelessly applied some commands they found on internet or from an LLM. Then it is very annoying to sit down and untangle the mess they created.

          And regarding the pushing without fetching, it is usually a different branch. So they won’t incorporate the new changes in the main branch into their working branch, but just push their work into a branch. Again not a big deal. Just annoying.

      • pmk@lemmy.sdf.org
        link
        fedilink
        arrow-up
        3
        ·
        2 days ago

        Is it ok to continue on a branch if you also merge back main into it? Like, branch gets merged into main on remote, local main pull, local merge main into local branch, push branch?

        • sorter_plainview@lemmy.today
          link
          fedilink
          arrow-up
          6
          ·
          edit-2
          2 days ago

          So this workflow is needed if you are working on a public, i.e. multiple devs collaborating on a single branch, scenario. But it is much better to avoid this as much as possible. Usually it is a ‘scoping’ issue, where you create a branch that is too broad. For example ‘api-for-frontend’, which is a massive thing.

          But let us say you absolutely have to get multiple devs on same branch, then this workflow is totally fine. There is nothing wrong in it.

          In our org we prefer to delete the branch after merge. In a way it says ‘this branch is closed’. This is to encourage devs to define smaller and more logically scoped branches.

          I want to take this opportunity to say that, branch is just a label on a commit, with some additional functions. Once you start focus on commits and lineage of the commits, then branches become some what irrelevant.

          • pmk@lemmy.sdf.org
            link
            fedilink
            arrow-up
            2
            ·
            2 days ago

            Aha. I was part of a project where each dev had their own long running branch for non-specific work and this was the norm, but it always felt clunky. And often resulted in merge issues.

            • sorter_plainview@lemmy.today
              link
              fedilink
              arrow-up
              2
              ·
              1 day ago

              That is a very weird setup. I have no clue why that flow is needed in the first place. Branches should be something disposable easily. What was the logic behind the setup? Any idea?

        • pinball_wizard@lemmy.zip
          link
          fedilink
          arrow-up
          4
          ·
          edit-2
          1 day ago

          Is it ok to continue on a branch if you also merge back main into it?

          On some repositories, sure.

          But better maintained repositories don’t allow merge commits (because merge commits suck), and so will have squashed (or rebased) on merge.

          (If squashed) The squash will have changed commit IDs, so a long running branch rebased won’t benefit from a clean shared commit history.

          So it can work, but “you’re gonna have a bad time.”

          In general, git works best if branches are thrown away as soon and as often as possible.

          (Edit: Good clarification in response below, added here for consistency and accuracy.)

          • Ephera@lemmy.ml
            link
            fedilink
            English
            arrow-up
            4
            ·
            2 days ago

            You don’t have to squash to avoid merge commits. Instead, you can git rebase main to update your branch. Effectively, this will rewrite the history of your branch, as if you had just branched from the main-branch and then instantly coded all your changes on top of that. (Well, the commit timestamps won’t change, but they will sit on top of the changes of the main-branch.)

            Afterwards, you should be able to merge into main by switching to it and then running git merge --ff-only your_branch.
            Because all the changes sit on top of the main-branch commits, it should be able to fast-forward. No actual merging needs to take place then. You’ve already resolved any conflicts while rebasing.

            This also allows you to keep branches for longer, so long as you frequently rebase and merge back.

      • panda_abyss@lemmy.ca
        link
        fedilink
        arrow-up
        3
        arrow-down
        2
        ·
        2 days ago

        I’ll get chastised, but when I screw up a rebase I create a backup branch and then have an LLM do the fixing…

        I’m not proud of it, but I’m a lazy man who doesn’t want to resolve the same conflict 32 times.

        • kibiz0r@midwest.social
          link
          fedilink
          English
          arrow-up
          9
          ·
          2 days ago

          Having to resolve the same conflict multiple times suggests excess noise in your git history. You might want to pay closer attention to creating a useful git history. It’ll help with any future archaeology, and it’ll also help rebasing go smoothly.

          • toynbee@lemmy.world
            link
            fedilink
            arrow-up
            1
            ·
            1 day ago

            I mostly only use git at work and I guess I’ve never had the same work machine long enough to worry about this. It helps that each of our repos is fairly small. At least the ones I touch.

    • ElectricWaterfall@lemmy.zip
      link
      fedilink
      English
      arrow-up
      3
      ·
      2 days ago

      I’ve even recovered from deleting local changes I forgot how but there is a way! (It’s not something to rely on but can help in a pinch!)

      • Ephera@lemmy.ml
        link
        fedilink
        English
        arrow-up
        7
        ·
        2 days ago

        Well, if you did commit it, but just hadn’t pushed it yet, and then somehow lost that commit, then git reflog would be the tool for it.
        Without a commit, sometimes you may have already staged some changes for an upcoming commit and can roll back to that.

        But if neither of those are the case, then I can’t really imagine how Git should help you there. You haven’t told Git about those changes yet, so it’s out of scope.
        At that point, you better hope your editor’s undo history goes back far enough…

        • ElectricWaterfall@lemmy.zip
          link
          fedilink
          English
          arrow-up
          2
          ·
          1 day ago

          This might have been what it was as you mentioned git reflog. I don’t remember clearly since I’m usually pretty good at not making this mistake.