GIT


Web Development

Updated Apr 1st, 2022

Git is a decentralized version control system that tracks every change made and can revert back if necessary. You have a “repository” on your local machine and then you push to a “remote” repository like GitHub or Bitbucket. You don’t need internet connection to use Git (until the push up to the remote).

Basic Commands Include:

git init
git status
git add .
git commit -m"Whatever Message Here"
git log --oneline --all -- decorate --graph
git branch
git checkout -b newBranchName
git merge
git merge --no-ff
git remote -v
git remote add remote origin pasteLocationHere.git
git remote set-url existingRemoteName newUrlHere.git
git clone
git pull
git rm

Note: when you initialize a local git repository there is a “.git” folder created in the directory and is “hidden” file by default so make sure folder search options are correct. You delete this folder if you want to delete the git history and start over.

Link to download and install Git on Windows is (http://git-scm.com/download/win) and the link to the docs is here. The Git install comes with “gitbash” which looks more linux-y and you may want to use this over command line.

May be better to learn commands than use the GUI tools that are available but that is personal preference.

The first time you set up you may need to use the following commands. I believe this process is outdated:

git config --global user.name 'whatEvsUsername'
git config --global user.email 'you@whatever.com'

Working area (your local machine) versus staging area (Files will be tracked on next commit).

The “.gitignore” file is very important

Pro-tip: make many small commits.

Checkout Confusion

What confused me for a while as far as “going back in time” or undoing work was that

The “git checkout branchName” command is used to move back and forth between branches. Simple. But it can also be used to throw away any untracked changes, (if say our cat walks across our computer in the middle of the night).

So “checkout” leads a double life in a way. It’s important to remember it will remove untracked changes from the working directory. Meaning taking the branch back to the state that it was at it’s last commit. In a way, checkout is navigating back to the state of the working directory as of the last commit on that branch.

Note: if you need to get rid of any tracked files you have to use “git reset –hard” which changes the git history or “git revert” which doesn’t change the git history but makes a new commit offsetting the changes.

Amend

Rename a commit message if its the most recent with “git commit –amend -m”Your New Message Here.” Can also add any files you forgot to add. The “git log –stat” command will show any files changed during a commit.

Note: Amend does change the git history.

Squash versus –no-ff –no-commit

Let’s say you create a test branch make three micro-commits on that branch and then want to merge back into a “main” branch.

Using the “git merge –squash squash-test-branch” command will combine the three micro commits on that branch into one commit. Then when you commit that, it represents the merge as one commit. Good for teams and/or when keeping things tight but you sacrifice the details of all of those individual micro-commits.

Note: the exact message after running the “git merge –squash squash-test-branch” command may be something like “fast-forward, squash commit — not updating HEAD” and the updated file/files are still in the staging directory waiting to be committed.

With the –no-ff option, When you do the same process and merge with the command “git merge –no-ff -no-commit test-branch” you will get a message in the console: “Automatic merge went well; stopped before committing as requested.” So then you can make commit, which is essentially the merge commit created by the –no-ff flag. The micro commits are still in the primary git history, and if you look at “git log –graph” there is an extra rail showing the micro-commits belong to the that feature branch. This offers more detail, ability to go back to a specific point but things are not as organized.

Cherry-Picking

Useful when you want to move one or some commits from one branch to another instead of merging the entire branch. Useful when you commit code on the wrong branch by accident and you need to move it.

Note: Not a replacement for merge and rebase.

Start by running “git log” to get the commit hash needed. From the correct branch cherry pick the commit over with the command:

git cherry-pick whatEvCommitHash

But the commit stays on the original/error branch so you need to clean this up as well with “git reset –hard HEAD~1” if it’s the most recent commit there.

Note: HEAD~1 means one behind the head.

Interactive Rebase

Use for cleaning up local repository. Clean up the commit structure. Delete, reorder, rename,

Warning

It changes the history (commit hashes) for all commits onward from whatever changes you make.

Rebase can be a bit tricky. It opens up a VIM editor, which for some may be a bit foreign. You see warnings like “you delete the wrong thing your commit will be gone forever.” It is an extremely powerful tool so see the commands inside the VIM editor to get a sense for all that rebase can do.

When selecting the commits to “act and operate on” for the rebase we use the “HEAD~X” approach where X is a number of commits back. This doesn’t include HEAD, so just grab an extra one for good measure.

Note: a stack overflow here about tilde versus caret.

Note: In the VIM Editor hit the “i” key to enter insert mode. Hit “escape : w q enter” to save and quit file.

The rebase editor shows commits in chronological order, the newest is on the bottom, which is the opposite of what we are used to seeing with the “git log –oneline” command.

You always have an option to abort your rebase with “git rebase –abort”

Note: Screwed something up big time? Run “git reflog” to find the commit before the rebase and then “git reset –hard HEAD@{2}” where the hash can be found from the reflog output.

Alternative to Merge Command

Rename Commits Beyond Most Recent

Squash

Note: When adding a commit message in the rebase prompt do not have any leading spaces.

The fixup keyword in the interactive rebase may be a good alternative

Reflog

Mentioned earlier in the rebase section, the “reflog” is like a diary for Git. Commits and branches hang around until they are garbage collected after a few weeks or 30 days or something. If you have deleted too much “permanently” you can potentially bring it back from the dead, at least for a little while.

Submodules

Search & Find

Sources

Great video here on FCC by Tobias G√ľnther from Tower, watch and re-watch.

Also, Corey Schafer has some of my favorite tutorials on the basics, stash, and fixing common mistakes.

Also the modern coder here