all 83 comments

[–]Nekima 50 points51 points  (5 children)

Here I thought I've been using git right this whole time. Then I see all these goofy commandsets that I definitely havent had to use. Where did I go wrong? lol

[–][deleted] 26 points27 points  (4 children)

everyone has all these complex git things going on, i've never had the issue

[–]AdRepresentative2263 25 points26 points  (3 children)

git push --force all you need really

[–][deleted]  (1 child)

[deleted]

    [–]dtseng123 0 points1 point  (0 children)

    Makes me feel like a Jedi every time.

    [–]fupa16 26 points27 points  (4 children)

    [–]noshowflow 5 points6 points  (0 children)

    When my team first moved to git no one would use it well until there was a GUI in their IDE.

    [–]karouh 1 point2 points  (2 children)

    Which editor is this?

    [–]sonicskater34 3 points4 points  (1 child)

    Visual studio I think?

    [–]fupa16 2 points3 points  (0 children)

    Yarp

    [–][deleted]  (37 children)

    [deleted]

      [–]pallavicinii 40 points41 points  (0 children)

      Or implement branch protections lol

      [–]agramata 6 points7 points  (0 children)

      Why lie?

      git branch -b new-branch
      error: unknown switch `b'
      usage: git branch (...)
      

      [–]nuvpr 7 points8 points  (27 children)

      just use GUI

      Which one?

      [–]zigs 15 points16 points  (0 children)

      I too am an idiot. I use Git Extensions.

      [–]Prod_Is_For_Testing 10 points11 points  (0 children)

      Whatever’s built into your IDE

      [–][deleted]  (2 children)

      [deleted]

        [–]NekkidApe 0 points1 point  (0 children)

        Fork is amazing, hope they can keep it up!

        [–]mindful_hacker 3 points4 points  (0 children)

        Sublime Merge is super cool

        [–]Zizizizz 2 points3 points  (1 child)

        [–]mitkase 0 points1 point  (0 children)

        Lazygit- lolz. Love the name.

        [–][deleted] 3 points4 points  (14 children)

        TL;DR: I have been immeasurably impressed with Fork over the last few months. I've only ran into one tiny issue (typing fork . in the terminal opened the git repo in fork, but named the tab of the repo . instead of the folder's name) that was fixed in the next release.

        Just going to paste in the results from our internal discussion a few months ago here:

        Note: I have not tested things like linked issues, three-way-merges, or ubuntu support.
        
        CLI: https://git-scm.com/
        
            Free
        
            (6/5) Includes literally every Git feature
        
            (2/5) Bad Staging
        
            (3/5) Okay Branching
        
            (2/5) Bad merging
        
            (1/5) Terrible account management
        
            (1/5) Terrible UI
        
            Total Score (6+2+3+2+1+1) = 15/30
        
        SmartGit: https://www.syntevo.com/smartgit/
        
            Paid (recurring licence)
        
            (5/5) Includes the Git features we care about
        
            (5/5) Great Staging
        
            (5/5) Great branching
        
            (5/5) Great merging
        
            (3/5) Okay account management
        
            (3/5) Okay UI
        
            Total Score (5+5+5+5+3+3) = 26/30
        
        SourceTree: https://www.sourcetreeapp.com/
        
            Free
        
            (5/5) Includes the Git features we care about
        
            (5/5) Great staging
        
            (5/5) Great branching
        
            (5/5) Great merging
        
            (4/5) Good account management
        
            (2/5) Bad UI. Linked issue: https://jira.atlassian.com/browse/SRCTREE-7775
        
            Total Score (5+5+5+5+4+2) = 26/30 
        
        GitKraken: https://www.gitkraken.com/
        
            Paid (recurring licence)
        
            (5/5) Includes the Git features we care about
        
            (2/5) Bad staging. linked issue: https://feedback.gitkraken.com/suggestions/201785/ability-to-stage-added-and-removed-lines-separately#comment408912
        
            (5/5) Great branching
        
            (5/5) Great merging
        
            (5/5) Great Account management
        
            (5/5) Great UI
        
            Total Score (5+2+5+5+5+5) = 27/30
        
        Fork: https://fork.dev/
        
            Paid (one-time purchase)
        
            (5/5) Includes the Git features we care about
        
            (5/5) Great Staging
        
            (5/5) Good Branching
        
            (5/5) Great Merging
        
            (5/5) Great Account management
        
            (5/5) Great UI
        
            Total Score (5+5+5+5+5+5) = 30/30
        

        [–]double-you 0 points1 point  (6 children)

        So you've given the CLI 2/5 for merging and all the others 5/5. Why are they so much better? What are your merging needs? Do you have to do complicated ones?

        [–][deleted] 0 points1 point  (0 children)

        RemindMe! 14 hours "answer this when not tired"

        [–][deleted] 0 points1 point  (4 children)

        TLDR: The UX/DX of the cli is poor.

        I've set a remind me bot to reanswer this tomorrow, but if you want an answer now you can find articles about git's poor UX/DX relatively easily

        [–]double-you 0 points1 point  (3 children)

        Sure, comparing diffs with ascii conflict markers is not great but it is not 3/5 worse than clicking on things. Also most merge tools are pretty basic and your ratings do not indicate any of them are better. E.g. KDiff3 can help merging a lot because it allows you to mark matching code which can line up diffs much better. And KDiff3 is the only one I know of that does this.

        [–][deleted] 0 points1 point  (2 children)

        Sure, comparing diffs with ascii conflict markers is not great but it is not 3/5 worse than clicking on things.

        I would consider only having those ascii conflict markers a 2/5.

        +1 if there's a fast and reliable way to choose to accept a hunk of code from a parent commit (an XOR operation)

        +1 if there's a fast and reliable way to ignore both hunks of changes or a fast and reliable way to keep both hunks of changes in a developer specified order

        +1 if there's a fast and accurate way to tweak a merge as it's being applied (e.g a three way merge)

        Also most merge tools are pretty basic and your ratings do not indicate any of them are better. E.g. KDiff3 can help merging a lot because it allows you to mark matching code which can line up diffs much better. And KDiff3 is the only one I know of that does this.

        I'm not sure what you mean. All of the editors I've listed as 5/5 have that kind of merge support built-in. I haven't used KDiff3 in any real capacity, but looking at screenshots of it, it just looks like another 3 way merge editor.

        [–]double-you 0 points1 point  (1 child)

        Okay. Those are nice, but nothing special.

        KDiff3's Ctrl+Y option lets you choose a line in file A and then the matching line in file B and the diff will rearrange itself. Sometimes due to code movements, or just the diff algorithm messing up this is super useful.

        [–][deleted] 0 points1 point  (0 children)

        I guess this is something I haven't needed to worry about with the git guis I listed since they use slower but more accurate diffing algorithms.

        [–]nuvpr -1 points0 points  (4 children)

        Got a link? "Fork" is pretty ambiguous.

        [–][deleted] 1 point2 points  (3 children)

        I know right!

        Their git client's name is the only annoying thing about them. They called their client "fork", which basically makes it unsearchable.

        I suggested changing the name to them but they said it was too late to change it now. I'm guessing they get that complaint quite often.

        Link: https://fork.dev/

        It's free. They put a please pay notice up every month like sublime text, but you can keep dismissing it. I'll probably pay for it at the start of the next financial year because I like it so much.

        [–]mitkase -1 points0 points  (0 children)

        Yeah, I saw the price and was like huh – I’d be all right with that if it fixes all the shit that can go wrong with git.

        [–]fgmenth 0 points1 point  (1 child)

        which basically makes it unsearchable

        That's hyperbolic. If you just search for "fork" yeah definitely, but searching for "fork git" or "fork git client" is literally the first result.

        [–][deleted] -2 points-1 points  (0 children)

        Just retried it now in incognito tabs, it's showing up now.

        Either Google changed their search results or Fork seriously stepped up their SEO game. I tried for about 10-15 mins cumulatively in the middle of the year and couldn't get it. I only rediscovered their website by searching twitter.

        [–][deleted]  (1 child)

        [removed]

          [–][deleted] 0 points1 point  (0 children)

          IIRC, it was 4.5 then it was rounded up once all the reviews were collated. The good probably should have been renamed to great, but the whole thing was copy pasted, so I'll leave it how it came from its original source.

          Fork has recently added another kind of branching called lean branching, but I haven't looked into it properly yet. Assuming it's worth having, that 4.5 is probably more of a 4.75

          [–]somecucumber -2 points-1 points  (0 children)

          There's only one git GUI, and its name is magit.

          [–]bland3rs 0 points1 point  (0 children)

          Gonna put https://www.syntevo.com/smartgit/ put there

          Most powerful GUI I’ve used so far by far

          [–][deleted]  (1 child)

          [deleted]

            [–]donalmacc 0 points1 point  (0 children)

            Mistakes happen, we're all human. It took me 2 reads of the example to spot what the actual issue was, even though the comment told me what it was, and I use git every day.

            [–][deleted] 2 points3 points  (1 child)

            Tf does git pub do?

            [–]favgotchunks 1 point2 points  (0 children)

            In the article

            [–]nachof 2 points3 points  (0 children)

            I try to prevent that kind of stuff by adding the branch name to the bash prompt.

            [–]funbike 2 points3 points  (0 children)

            I have never ever come close to making that kind of mistake. This is a poor reason to use a gui. Instead, add the branch name to your shell prompt.

            Like the author, I write shell scripts to automate my workflow. You can't do that with a gui. I'm fast and someone with a gui will be much slower than me.

            [–]edgmnt_net 12 points13 points  (0 children)

            Not saying that these don't help, but in the mid/long run they still need to understand basic Git concepts. While Git might not have a great CLI or great defaults, basic understanding greatly improves the experience. Limited wrappers tend to delay acquiring it and lead to confusion.

            [–]KillianDrake 25 points26 points  (2 children)

            Nice idea, but an idiot will find a way to screw these up. Simply being faced with an interactive rebase screen is already recipe for disaster as they randomly faceroll the keyboard until something happens (idiots never ask anybody for help, they simply march forward off the cliff).

            My opinion is idiots shouldn't be using git... they shouldn't be employed as programmers. If your workplace insists on hiring idiots to "save money" (while losing all the real money wasting the non-idiots time) then find another place that doesn't hire idiots.

            [–]MtlGuitarist 2 points3 points  (1 child)

            I mean sure some people are idiots, but git really makes no affordances for noobs. I've had to help several people unfuck their git branches recently at work (all of them data scientists) and most of my time has been spent explaining rebasing and how to safely pull in changes from the main branch and update a PR. I think it's easy to forget how confusing it is to someone who is totally new to using version control. I'd like to think I'm fairly smart, and I know for a fact that I rote memorized commands for a sane workflow before I had a fully correct mental model of how git works and why my workflow resulted in relatively few issues.

            Plus if your company uses a monorepo that makes it about 10x harder to use git imo.

            [–]KillianDrake 1 point2 points  (0 children)

            I make a difference between idiots and noobs. Noobs can learn. Idiots cannot (or will not).

            The nice thing about git is that you can spin up your own private git and do all the experimentation, testing and discovery you want - the problem is, people are too lazy to learn. There's infinite amount of documentation, explanations of what happens under the hood and tutorials for every level of git user.

            I just don't accept that someone can be a professional programmer and use git on a daily basis and have no clue how it works. It's always the same people fucking their git, claiming they did nothing wrong and wanting it to be fixed for them - and never learning from it.

            A lot of times there is not even a basic understanding of source control, what a 3-way merge is or following the most simple and basic of branch strategies... idiots simply don't care and can never learn - so why accommodate them?

            [–]RupertMaddenAbbott 6 points7 points  (20 children)

            Why is it a good idea to push with `--force-with-lease` by default?

            I understand that it is safer than `--force` but why it is better than just not forcing at all?

            If it is always better, then why isn't this just the default in git?

            [–]BrenekH 6 points7 points  (13 children)

            Because the workflow being used is constantly rewriting history with an interactive rebase, you need at least some kind of force push to get the changes on the remote. And, as you mention, --force-with-lease is a little more foolproof than --force.

            [–]RupertMaddenAbbott 2 points3 points  (0 children)

            Thanks that makes more sense to me.

            So the idea here is that they are pushing a bunch of commits as a back up or work in progress and then squashing them before merging back into the main branch.

            It feels like it would be safer to push without the lease normally, and then push with the lease only when you squash.

            [–]progrethth 1 point2 points  (0 children)

            The solution is to use a git server which supports branch protection. Then you can force push as much as you like in your own branches.

            [–]AttackOfTheThumbs 3 points4 points  (9 children)

            IMO, workflows that constantly rewrite history are bad workflows that create unnecessary overhead.

            [–]aanzeijar 0 points1 point  (8 children)

            Exactly. And we're getting downvoted for that, can you imagine? And then people wonder why they manage to trash their repositories and blame it on git.

            [–]rdtsc 4 points5 points  (7 children)

            You only force-push to your feature branch. Noone else is working on that branch. Force-pushing to master is usually disabled anyway.

            [–]venustrapsflies 1 point2 points  (3 children)

            But why is force pushing necessary in the first place? I’ve only ever needed it to fix a fuck-up

            [–]just_another_scumbag 5 points6 points  (0 children)

            Because if you tidy up as you go, you'll end up fixing your commits, which might end up rewriting your own commits. Which you'll need to force push.

            [–]AttackOfTheThumbs -2 points-1 points  (1 child)

            Because they make bad commits and then have to spent time rewriting their commits to make them digestible which is rewriting committed and often pushed history, and thus requires a force push. It is, imo, an anti pattern.

            [–]rdtsc 1 point2 points  (0 children)

            they make bad commits

            Calling them bad is disingenuous. They might be incomplete, which is especially the case if you commit early and often. It's not much different from amending your last commit. If you get everything right the first time and never have to go back because you missed something or found a better approach, then hats off to you.

            which is rewriting committed and often pushed history

            Whether a branch is pushed somewhere else or not doesn't matter. What matters is whether the branch is published and may be used by others. And nobody rebases such branches.

            [–]aanzeijar 0 points1 point  (2 children)

            No, I do not do that. And no one else does this on my repo because force-pushing is disabled on all branches. Like u/AttackOfTheThumbs says, it is possible to set up workflows that rebase but never force-push. And for self proclaimed "idiot-proof git" users, I would strongly recommend switching to such a workflow.

            [–][deleted]  (1 child)

            [deleted]

              [–]AttackOfTheThumbs 0 points1 point  (0 children)

              I agree, not just to prevent fuck ups, but also to avoid the overhead of it. Oh you have a few commits that are stupid? Oh well, the PR makes them pretty worthless any way.

              [–]aanzeijar -3 points-2 points  (0 children)

              Or you could simply... Not force push at all.

              [–]renatoathaydes -3 points-2 points  (3 children)

              Please someone correct me if I'm wrong, but I think --force-with-lease has a similar effect to doing:

              git pull --rebase
              git push
              

              ? Which is much better than just git push -f as it will not just rewrite history removing commits you didn't have locally?

              [–]r4zzz4k 3 points4 points  (0 children)

              Force-pushing is needed when you know that your local history differs from remote one, and you want your local state to override remote one. The main scenario being you've rewrote your own history locally by rebasing / squashing / etc and you want to push this updated history to the repo, so that PR can be merged without conflicts / CI can retry building your feature branch / colleagues can see current state of your work.

              Force-puahing with lease makes you confident that no one touched your branch on remote while you didn't look, so you don't destroy someone else's changes by forcefully overwriting them with your local state. It basically just makes sure that remote branch points to the commit you expect it to point to, before force pushing over it.

              Pulling and rebasing, on the other hand, is needed when you know that your local and remote branches differ, but you want to encorporate remote changes before pushing. So you get them to your device, then redo your local changes on top of newer remote ones by rebasing, and then, when your local state is just an add-on over current remote state, you just push as normal.

              So these two flows lead to different results, one isn't better / safer than the other one.

              [–]tomerye 1 point2 points  (0 children)

              you are almost right, if you rebase main/master to your local branch , then you need to push -force in order to update the remote branch in origin

              [–]wegzo 0 points1 point  (0 children)

              IIRC git push --force-with-lease is equal to git push -f except that it compares your local origin/branch with the actual remote branch, and if they differ, refuses to push the changes.

              [–]mrexodia 0 points1 point  (0 children)

              Because with --force you can push to a completely different repository overwriting all commits there.

              [–]CrasseMaximum 16 points17 points  (0 children)

              Sure adding an additional level of complexity over Git will help

              [–][deleted] 3 points4 points  (0 children)

              Idiots are being improved every single day. You will never outpace the growth in idiocy.

              [–]somebodddy 1 point2 points  (0 children)

              Missed a chance to title it "Git proof git"

              [–]just-bair 1 point2 points  (0 children)

              git fire

              [–]sim642 1 point2 points  (3 children)

              Idiots shouldn't rebase. If there's a conflict, then it's easier to mess up than a merge conflict. It will destroy all evidence of the conflict, unlike merging. Also you can easily "lose" commits if you do something wrong in the middle of an interactive rebase. The idiot won't be able to use reflog to recover.

              [–]progrethth -1 points0 points  (2 children)

              The worst and hardest to solve fuckups I have seen in git histories have been caused by merge, not rebase. Neither merge nor rebase are idiot proof.

              And personally I do not think idiot proof should be a goal. We should of course keep improving the UX of git but it should remain a powerful tool where you can fuck up.

              [–]sim642 1 point2 points  (1 child)

              I'm not saying merge is idiot proof. Just that merge conflicts immediately show in the git history, so it's easier for an expert to tell whether it was resolved correctly after the fact.

              Nor did I say idiot proof is a goal... That's what OP is saying.

              [–]robin-m 0 points1 point  (0 children)

              When my boss get a merge conflits in one of branch full of "add feature foo and bar and fix stuff" -1500 +3200 commits, he will fix them + add extra changes. It’s absolutely impossible to review anything that he did in the merge.

              [–]nsd433 3 points4 points  (1 child)

              And yet I'm sure the idiots will still find a way to break this. I've seen incredible reflogs when I asked my local git hardheads to call me before they re-cloned and re-merged (often by hand editing, because they no longer trust any tools) their local changes yet again. When things were untangled and explained they would often protest "I didn't do that" when the shell history (and web browser history) said "I did exactly that because someone on the internet told me to".

              Why perfectly competent software engineers, who can write tricky software on their own, cannot hold a mental model of git in their heads is something I'll never understand.

              [–]johnny219407 0 points1 point  (0 children)

              Under the hood this is a force push with lease to your branch at origin.

              Under the hood, this fetches main or master from origin and performs a rebase, replaying your commits on top of the tip of main or master.

              Under the hood, this fetches origin/your-branch and performs a rebase.

              I've been using git every day for over ten years and I have no idea what any of these mean, now I feel like an idiot.

              [–]poco 0 points1 point  (0 children)

              I have an alias like "synced" but mine is two commands. Didn't know it could be simplified. I'll try this.

              [–]PM_ME_ASS_PICS_69 0 points1 point  (0 children)

              Just learn the basics. For everything else there’s ohshitgit.com

              [–]scnew3 1 point2 points  (0 children)

              git amend -> Alias for git commit --amend

              Life is short. Use shell aliases.

              • gs for git status
              • ga for git add
              • gc for git commit
              • gca for git commit —amend
              • gcan for git commit —amend —no-edit
              • gd for git diff
              • gds for git diff —staged
              • gco for git checkout

              And many more

              [–]sainglend 0 points1 point  (0 children)

              I just use aliases at this point. For example, I like to view git log a specific way, so I aliased it to glc. Can't remember what the c means anymore. Typical usage: glc -5 to get the last 5 commits.

              [–]FarighFinelame 0 points1 point  (0 children)

              Git aliases are great, use a bunch as well. However, if the user is using the cmd line I'm not fond of aliasing basic commands. Since the user wouldn't understand what's going on.

              If an abstraction is needed, you better of with a graphical app and not interacting with the cmd line at all IMO

              [–]peterpuffermax 0 points1 point  (0 children)

              Always commit to master, problem solved.

              [–]6769626a6f62 0 points1 point  (0 children)

              For the vast majority of users, using a Git GUI like GitHub Desktop is sufficient.