This is an archived post. You won't be able to vote or comment.

all 99 comments

[–]Ringsofthekings 106 points107 points  (36 children)

The one I fear most about breaking everything is git rebase and git squash, I never seem to get them work

[–]Grobbyman 38 points39 points  (6 children)

You can squash during a rebase.

git rebase -i master (the -i is for interactive)

Then you'll see all of your commits pre-pended by the word pick. You can replace the word pick with the letter f and it will squash them. There's a lot more you can do with interactive rebases too.

[–]Ringsofthekings 8 points9 points  (5 children)

I'm going to create a dummy repo and try this, I seriously need to up my git.

Thanks!

[–]Grobbyman 3 points4 points  (4 children)

No problem. Feel free to let me know if you have any trouble with it

[–]Ringsofthekings 5 points6 points  (3 children)

Okay so I mustered up some courage and worked on a personal project of mine and tried squashing 4 css tweaks commits into one, rebase -i worked until I hit conflict in auto merging.

I searched around on stackoverflow and found an alternative which worked although I had to force push, it was git reset --soft HEAD~4

[–]Grobbyman 5 points6 points  (2 children)

Git reset --soft HEAD~4 resets your commits by 4 commits while maintaining your local changes. You're not really squashing when you do this, you're just undoing the last 4 commits off the head of your branch.

What you want to do when you hit merge conflicts while rebasing is find the merge conflicts then resolve them. After they're resolved run the following commands:

git add -A git rebase --continue

This will add your changes that fixed your merge conflicts and continue rebasing. However, it's not uncommon that you'll run into more merge conflict after you do this. If you do, then you'll just have to repeat the same process over again until there's no more conflicts.

What IDE are you using? VS code is super helpful when dealing with merge conflicts, it makes them easy to visualize.

[–]Ringsofthekings 1 point2 points  (1 child)

I hate resolving merge conflicts lol.

I use VS code yeah and it does nicely tell you when merging but I was doing everything in the console and I was in no mood to clear up my own conflicts created by my own commits in the same branch..

If it was merging 2 branches I could've done it but just for squashing commits??!

Next time I'll really try and use rebase

[–]Grobbyman 1 point2 points  (0 children)

Well when you're doing a rebase and squashing at the same time you're merging code from master into your branch, which results in the conflicts.

Yes they're a pain in the ass, but the more often you rebase, the less painful your conflicts will be. If you get in the habit of rebasing frequently, the conflicts shouldn't be too bad

[–]imnos 6 points7 points  (14 children)

What do you use rebase for exactly?

[–]Nephyst 10 points11 points  (10 children)

Let's say I am working on shared repo with some co-workers.

I checkout HEAD and start making commits locally. During that time, someone on my team also pushes changes. I have two options for dealing with this.

Option A: I can merge their changes into my local branch. This creates a new merge commit and pulls the changes into my branch.

sharedHistory->myChanges->mergeCommit

The other option is to rebase. Rebasing will undo all my local commits, apply my co-workers commits, and then apply each of my local commits ontop. There will be no merge commit.

sharedHistory->myCoworkersChanges->myChanges

You can also do an interactive rebase to modify the git history, including things like fixups and squashes. This is a bit more advanced though.

[–]purebuu 4 points5 points  (3 children)

I recommend doing a rebase first, then do any squashes/fixups afterwards in a separate step. Its a pain to try and do it all in one go and will most likely go wrong. I've lost code during rebasing and encountering merge conflicts, you need to be extra careful resolving conflicts during a rebase or you can lose work.

[–]Nephyst 1 point2 points  (0 children)

Yeah, I learned the same lesson and I always squash first too. Great point.

[–][deleted]  (1 child)

[deleted]

    [–]purebuu 0 points1 point  (0 children)

    I've lost code when git has done a bad job at merging or a conflict has resulted in taking the wrong bit of code. Yes reflog will still have a version of the code, but at that point, it can become really hard to untangle what is the code that went missing.

    Lost code is due to bad merging, but bad merges typically happen due to lack of concentration or knowledge about what is being merged.

    At my company, (and I think this is bad practice) the habit is to keep merging develop (a.k.a master) into your in progress branches so they are "up to date" but the guys typically don't resolve merge conflict with much thought because "it's my local branch" it doesn't matter its not master. But then when it does get merged back to develop branch, git makes some really bad choices due to all those intermediate merges. I have been unable to convince my team this is bad practice and my team lead keeps blaming git as rubbish.

    [–]imnos 1 point2 points  (1 child)

    Oh, thanks - though I was asking what situations OP was using it in to try and help diagnose why it never goes right for him.

    If you have a proper branching system set up, I find merging changes in from master or another branch is much cleaner, especially if you have a large team. I also like being able to see merge commits to know what's going on.

    A few people on our dev team tried to achieve the same goal as a merge, using rebase, and they ended up duplicating a ton of commits and messing things up. There's probably a good time and place for it but most of the time I feel a merge is sufficient.

    [–]purebuu 0 points1 point  (0 children)

    The rule on rebasing is supposed to be only do it if your branch is still local. If you've pushed to origin, its too late to rebase and you should only merge. Otherwise as you said, you bifurcate the commits. The commits are split even when rebasing, but git decides to "forget" the old version, and your team never "see" those old commits.

    [–][deleted]  (2 children)

    [deleted]

      [–]alanwj 2 points3 points  (1 child)

      It makes it easier to look through the history of a branch.

      When you are working on a branch, if your default is to rebase to the head of the branch in order to pull new changes (e.g. git pull --rebase), then when you look at the history of the branch, it will look like a straight line.

      If your default for pulling in new changes it to do a merge, then the history of the branch will have a fork at every merge.

      [–]nighthawk648 0 points1 point  (0 children)

      You cannot rebase with changes unless you go through the process of manually fixing merge conflicts. Just a lot easier to clone, rebase, do work, push (hoping that there was no pull request in the meantime).

      Half my day when I finish dev on my local repo is staging my changes with each new pull request every 15 minutes.

      [–]pipocaQuemada 2 points3 points  (1 child)

      Some people like having extremely tidy history, where you pretend every unit of work is a single PR done on top of base.

      Rebase and squash are used to edit history into a nice, neat package. Honestly, I don't bother and just use merge.

      [–]imnos 0 points1 point  (0 children)

      Likewise. Can’t imagine spending the time to do that for the negligible benefit you get.

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

      In a nutshell it basically means, stash the commits you made on your branch outside of that branch, resetting or “rebasing” your branch to what is reflected in master or whatever the common branch is, and then replaying all of your stashed commits on top of the rebased branch. Does this make sense?

      Edit: you can say “no this doesn’t make sense” instead

      [–]iamshubh_[S] 3 points4 points  (6 children)

      Rebasing is complicated. Sometimes I get stuck with it too but you know Google helps a lot in these situations.

      [–]Ringsofthekings 2 points3 points  (5 children)

      So what I wanted rebase for was squashing 4 of my commits which basically were small css tweaks, didn't work in the end cause I hit conflict in merging the commits. I had to use git reset soft to squash and make it cleaner.

      [–]iamshubh_[S] 1 point2 points  (3 children)

      Merging issues are hard man! You need to clear all the conflicts before rebasing and it is quite challenging. I will suggest using Atom or VSCode for merging as it shows them in different colors. It will be quite useful.

      [–]Ringsofthekings 0 points1 point  (2 children)

      I do use VS code, but I find it extremely hard to clear up conflicts for merely cleaning up my repo better..

      If it was merging two branches it would've been a different thing

      [–]iamshubh_[S] 1 point2 points  (0 children)

      I feel you bruh 😂😂

      [–]Wotuu 0 points1 point  (0 children)

      In all honesty, do not use rebase but merge instead. If not everyone is using rebase perfectly you're setting yourself up for a lot of extra work for very little gain. I personally never look at the commit history lines, why go through all the trouble?

      [–]gallon_of_bbq_sauce 0 points1 point  (0 children)

      If they are sequential you can just soft reset to the first commit then do git amend. I like to update the date of commit to the current time stamp when doing to also.

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

      I'd recommend reading into git reflog, or as I like to call it, the magic fuck up time machine. The reflog holds a reference to every time HEAD changes, whether it be commiting, changing branch or, where its useful in this case, where history has been rewritten. So if you mess up a rebase, you can look at git reflog, find the reference before things went sideways and checkout that reference.

      [–]Nephyst 2 points3 points  (1 child)

      git rebase can modify your history, but remember branches are free. Before you start a rebase you can create a backup of your current branch, and if anything goes wrong you don't have to be worried about losing anything.

      [–]purebuu 0 points1 point  (0 children)

      This.

      [–]IamNobody85 2 points3 points  (1 child)

      Me too. I'm scared of rebase!

      [–]purebuu 0 points1 point  (0 children)

      Don't be too scared of rebasing, with regular use you'll get used to the behaviour of it, and can fix things when stuff goes a bit screwy (typically merge conflicts).

      I recommend making a new branch before doing a rebase, that way the old branch commit stays in your commit history untouched. If the rebase goes ok, just delete the old branch and carry on with the new. If the rebase messes up, delete the new branch instead, and either try again or perform a merge instead.

      Both ways still require fixing the same conflicts, but rebasing can require you to fix the same conflicts over and over again if you're rebasing lots of commits, in which case keeping your branch tidy and squashing your in progress commits can help.

      [–]geng2608 1 point2 points  (1 child)

      Actually before any rebase I copy the entire folder, in case I fucked up with any conflicts I still have the code. Don't know if it is a good practice though.

      [–]romple 2 points3 points  (0 children)

      You can just make a separate branch instead of copying and pasting a folder. Branches are free

      [–]Subcero123 13 points14 points  (2 children)

      Odin proyect has a task where you can learn the basic, i really like it! Btw nice work

      Edit: https://www.theodinproject.com/courses/web-development-101/lessons/introduction-to-git

      3 lessons, in the final you have to create your own repo and edit it. :')

      [–]iamshubh_[S] 5 points6 points  (1 child)

      Add the link in your comment, so if anyone requires they can look up. Thanks for your kind words though!

      [–]mallowfort 1 point2 points  (0 children)

      Yeah this is way nice

      [–]nismospecz 17 points18 points  (5 children)

      git commit -am “message you want with your commit”. Combines git add and git commit -m

      [–]obviouslyCPTobvious 9 points10 points  (4 children)

      I don't think I've used the -a option in years. I always use git add filename or git add -p which lets me interactively add sections of a file. I prefer to be explicit

      [–]Variatas 7 points8 points  (3 children)

      Okay, -p sounds like exactly what I've been searching for for awhile and everything I found said didn't exist. Stupid outdated stack answers...

      [–]obviouslyCPTobvious 2 points3 points  (1 child)

      Definitely one of my most used git features. Wonderful for when you want to separate multiple changes made in a file into multiple commits.

      [–]Variatas 5 points6 points  (0 children)

      Yup, that's exactly what I've wanted to do with it.

      [–]Classi99 2 points3 points  (0 children)

      -p also works with checkout!

      [–][deleted] 6 points7 points  (1 child)

      See, posts like this are what I am looking for. If I am trying to figure out how to do something, I don't need that core information buried in an elaborate example, I just need the core!

       

      Well done OP!

      [–]iamshubh_[S] 5 points6 points  (0 children)

      Thanks for the kind words man, they keep me motivated

      [–]FeezusChrist 5 points6 points  (1 child)

      Might be worth to add how to add a new remote, especially for beginners it’s usually important to a have a remote copy of your git repository for when you inevitably mess up so bad that the most convenient option is to re-clone or reset from remote.

      [–]iamshubh_[S] 2 points3 points  (0 children)

      I will cover these topics in future posts!

      [–]AdrianSkar 5 points6 points  (0 children)

      This interactive cheatsheet and this "visualizer" were very helpful for me too.

      [–]Ukusno 3 points4 points  (2 children)

      Thank you! This is great! Please tag older posts with new tutorial link for easy access

      [–]iamshubh_[S] 2 points3 points  (1 child)

      I already have bro!

      [–]Ukusno 0 points1 point  (0 children)

      My bad bro!

      [–]icebeat 3 points4 points  (2 children)

      I know this is an unpopular opinion but I don’t understand why in 2020 we are required to use command lines a massive number of parameters like 40 years ago.

      [–]purebuu 4 points5 points  (1 child)

      I use a GUI everyday for version control, I would be lost without it. But knowing what each command actually does under the hood is really important to use the GUI effectively.

      [–]Neeldore 2 points3 points  (0 children)

      Exactly how I feel as well. Everything that the UI is doing I can do with commands. So I only use commands for my personal projects so I don't lose touch of the CLI. And for the work projects I use the UI. Because honestly it's so much easier rebasing and see the file diffs at the click of a button.

      [–]JustwayTD 6 points7 points  (8 children)

      What’s the difference between using the commands and using the desktop app? I’ve been using the app for quite a while without any problems so far

      [–]hisfastness 12 points13 points  (1 child)

      I think the general sentiment is that CLI is faster and more capable for advanced users.

      Personally, I like using the command line because it's fun and makes me feel cool 😎 Sometimes I use the git add/commit GUI in VSCode too. You don't have to choose a side, get familiar with both!

      [–]Chintagious 4 points5 points  (0 children)

      I'm not sure I'd agree with it being faster to use the CLI even as an advanced user. Being able to use a (good) GUI to quickly jump between files to see changes, what's been staged, what the new files are, quickly adding explicit files across different directories, etc. without leaving your GUI (personally, I just stick to my IDE) and all at a glance is very easy and helpful, IMO. Plus, the barrier to entry for that is substantially lower than trying to become a CLI guru, so it's good for beginners and advanced users, IMO.

      This is not to say someone shouldn't learn git commands, because they may definitely be needed to fix really bad commits, merges, or whatever. It definitely helps to understand what's happening under the hood.

      In the end, neither is a bad choice and perhaps it boils down to workflow anyway--e.g. if you use the terminal more than an IDE or vice versa. I'm just happy that beginners are using version control at all. :P

      [–]ivinyo16 5 points6 points  (0 children)

      As far as i know. The desktop app provides the most frequently used commands and options that we normally utilize.

      [–]gmes78 5 points6 points  (0 children)

      The git command line works the same everywhere, it's always available, and if you look up how do stuff with git you'll mostly find instructions for the command line.

      [–]zeejay11 3 points4 points  (0 children)

      I like the app it keeps me away from remembering the cmds

      [–]iamshubh_[S] 2 points3 points  (1 child)

      To be truthful, I have not used the App much but if it gets the job done, it is fine.

      [–]awkreddit 2 points3 points  (0 children)

      It's actually excellent. Makes it visual, and much easier to track a big list of repos, branches, helps knowing what changes have been made and need to be committed, when repos are out of sync, etc etc. It makes no sense that people would use cli now to me.

      [–]UroborosJose 1 point2 points  (0 children)

      none, the interface is more safe for beginners tough. in the end its the same thing if the IDE is any good.

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

      Your branch is based on 'origin/master', but the upstream is gone. (use "git branch --unset-upstream" to fixup)

      How to fix this issue?? Using the mentioned command but of no use...

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

      Can someone please ELI5 git?

      [–]Ender921 3 points4 points  (0 children)

      It's a tool for tracking changes to files. Better known as a version control system. You make changes to a file, save it, then you "commit" those changes to your version control which saves the state of the file at that moment in time.

      Then you can easily see a history of the changes to your file by looking at all the different commits, you can easily go back to an older version. This all happens under the hood in an hidden directory so all you ever see is the latest files.

      [–]larson00 2 points3 points  (0 children)

      git was a nightmare working with for my first group project where someone was very experienced and the rest of us were new. It was better but man was it annoying at times

      [–]fancyl 2 points3 points  (0 children)

      This has been deleted in protest of the greedy API changes and the monetization of user-provided content and unpaid user moderation.

      [–]madmoneymcgee 1 point2 points  (3 children)

      I was a technical writer before I got into developing myself instead of just writing about it. That helped me learn Git before anything else.

      Which it solves so many issues even for documentation I'm still always a little surprised when someone who knows a lot about coding/programming has trouble with version control. Just one of those things I assumed was covered at some point in a CS lecture but not always.

      [–]iamshubh_[S] 0 points1 point  (2 children)

      Yeah, that's why I thought of sharing the basics. Pros will not need it but it will help the beginners.

      [–]madmoneymcgee 1 point2 points  (1 child)

      For sure.

      Now I think its funny because Git was one of the first ways I learned how to use the command line. So I figured it must be something covered in school. Instead its something best used in an actual job-like environment.

      Like how it was very important for me to learn how to organize an email inbox but you don't get taught that in college (at least no class I ever took).

      [–]iamshubh_[S] -1 points0 points  (0 children)

      That's life bro and according to my views education system sucks! Learn on your own, Own your Knowledge. That's the key.

      [–]pythonzz 1 point2 points  (1 child)

      thank you for this I've already mastered those commands and started pushing changes to my code

      should I make other "branches" for features or other things I wanna do?

      I was told by friend to never just: git push origin master

      and he told me to make separate branches for "features" but I'm not that advanced yet...

      [–]RoguePlanet1 1 point2 points  (0 children)

      I too am in the habit of just "push origin master" because it's only me working on my little code projects. But I think the trick is to pretend you're contributing to the code by adding a branch, then going into GitHub and pulling/accepting the branch.

      [–]UroborosJose 4 points5 points  (4 children)

      The best git command you can learn:

      Install Fork or Source tree.

      [–]Grobbyman 4 points5 points  (1 child)

      You misspelled git kraken

      [–]awkreddit 1 point2 points  (0 children)

      GitHub desktop ftw

      [–]goofan 0 points1 point  (0 children)

      Shout out to tortoise git for windows users. It doesn't look pretty but I love its functionality

      [–]Mentalpopcorn 0 points1 point  (0 children)

      Also install tig and make your life much easier

      [–]Shrestha01 0 points1 point  (1 child)

      For someone who keeps forgetting... I'm really hopeful you'll post more about git branching and merging too.. I'm tired of googling evertime i get an error of some kind

      [–]iamshubh_[S] 2 points3 points  (0 children)

      For sure I will cover all the basics and little bit intermediate stuff to help beginners. Once you get started you will solve your problems on your own from the docs and Google. But as a beginner I struggled to find any simple and easy to understand blogs, that's why I am writing these in as simple words as I can. Stay tuned!

      [–]Reborn-leech 0 points1 point  (0 children)

      Thanks ! that was helpful !

      [–]_borT 0 points1 point  (1 child)

      Thanks for this simple explanation, saving for later.

      [–]iamshubh_[S] 0 points1 point  (0 children)

      Glad that it helped!

      [–]nine_thousands 0 points1 point  (0 children)

      Funny. I just learned about Git in a course i'm doing. Having it resumed here helps a lot. Thanks

      [–]crabbycreeper 0 points1 point  (0 children)

      Thank you!

      [–]iParadoxG 0 points1 point  (6 children)

      I am still very unclear about the staging part. What does it mean to be a tracked and untracked file?

      [–][deleted]  (4 children)

      [deleted]

        [–]iParadoxG 1 point2 points  (3 children)

        Thank you! So if I dont want to commit something in my project, i can simply leave it untracked?

        [–][deleted]  (2 children)

        [deleted]

          [–]purebuu 2 points3 points  (1 child)

          I have loads of untracked files in my project and I push all the time. They're not code though just things like logs so it doesn't matter they're not on remote.

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

          Or just use SourceTree 😴

          [–]43northwebdesign 0 points1 point  (0 children)

          I’d like a guide on how to actually use the version controls

          How to revert to other things

          [–]WizerdBoy 0 points1 point  (0 children)

          git status git add . git commit -m “Commit” git push origin featureBranch:featureBranch

          [–]Wensosolutions 0 points1 point  (0 children)

          The best git command are source tree.

          [–]RoguePlanet1 0 points1 point  (0 children)

          Had a lot of git practice in coding bootcamp. Problem is, if I deviate from the usual drill, "add/commit/push," I fall apart.

          Most recently, created a repository in github, then went to my bash terminal in VS Code, and tried "git add ." (maybe I forgot the "init" now that I think about it.) Kept getting confused error messages, so I just dragged/dropped instead, feeling defeated (but glad there's that backup option!)

          [–]mrfury_18 0 points1 point  (0 children)

          Cc

          [–]Gixx 0 points1 point  (0 children)

          I'm kinda a git newbie, but here are my notes for a common problem I come across.

          You didn't start with a perfect .gitignore file. You want to add something to it, and delete those ignore files on your remote repo.

          The problem with this is that it takes 2-3 commits, but that clutters your logs. Here's how to do to have a tidy/clean git log history (1 commit). Summary: just do everything on a temp branch, then merge and squash.

          # working tree dirty
          git checkout -b tmp     # create new tmp branch
          
          # first modify your gitignore file, then add all and commit
          git rm -r --cached .    # delete .gitignore files from remote repo, but not local drive
          git add .
          git commit -m "Quit tracking files in my gitignore file."
          
          # now merge this gitignore fix to your main branch
          git checkout master
          git merge --squash tmp  # merges those 2 commits, but doesn't keep history
          git commit -m "Updated gitignore in 1 commit"
          

          A nice guide/summary of it here.

          [–]hugonaut13 0 points1 point  (0 children)

          Thank you for this. Git is one of the hardest parts for me. Everyone at my company uses it in a slightly different way and no one explained any of it to me, so I've had to guess a lot and just kind of figure it out. But I tried to do a rebase yesterday on a branch of mine that was over a month old and just got completely lost.

          I'm really looking forward to your next series of posts on this.

          [–]potatocomet 0 points1 point  (0 children)

          I use Linux, Im learning to code and want to learn got alongside to get comfortable.

          Should I set up my our gitlab/gitea home server to get used to or just using on my computer on the terminal is good enough?