Table of contents
Basic Git Configuration
It is very helpful to have a .gitconfig
file. You can have a global one that sets defaults on all git repositories (~/.gitconfig
) and then repository specific .gitconfig
files as well.
To start with, make sure that you have a global .gitconfig
that sets your username, email, and your editor of choice for writing commit
messages.
git config --global user.name "Firstname LastName"
git config --global user.email "yourEmail@email.com"
git config --global core.editor "yourFavoriteTextEditor"
To check the settings of your .gitconfig
you can either just list it out
cat ~/.gitconfig
or you can query it for specific commands
git config user.name
Helpful aliases
I would also recommend setting up the following aliases
git config --global alias.pl 'pull --rebase'
git config --global alias.glog 'log --graph --oneline --decorate --all'
git config --global alias.fstatus '!git fetch -p && git status'
git config --global alias.ftag '!git tag -d $(git tag) > /dev/null 2>&1 && git fetch --tags > /dev/null 2>&1 && git tag'
git config --global alias.incoming '!f() { git fetch && git log ..origin/$(git rev-parse --abbrev-ref HEAD); }; f'
git config --global alias.outgoing '!f() { git fetch && git log origin/$(git rev-parse --abbrev-ref HEAD)..; }; f'
git config --global alias.last-files '!f() { git show --name-only $(git rev-parse HEAD); }; f'
For more high-powered Git aliases I'd recommend Tim Pettersen's Git Merge 2017 talk.
This is a walkthrough of how to do some basic things in Git
On GitHub/GitLab make a new repo called my-repo
. Use the web GUI to copy the URL to your clipboard and then clone it to your local machine
git clone <the URL you copied>
cd my-repo
GitHub | GitLab |
---|---|
Create a README
and license for your repo
touch README.md
# edit README as desired
touch LICENSE
# edit LICENSE as desired
Add and commit the files
git add README.md
git add LICENSE
git commit -m "add README and LICENSE"
# have the changes be tracked
git push -u origin master
Toy example of a workflow
Create a development branch to do work in
git checkout -b dev
#git push -u origin dev
Make an edit to the README
such as
This is a local edit to the README!
commit the change
git add README.md
git commit -m "Edit the README locally"
We're going to purposely make a merge conflict later by going to GitHub/GitLab and making an edit to the README
on the master
branch on there
This is an upstream edit to the README from the web!
GitHub | GitLab |
---|---|
On your local machine switch to master branch
git checkout master
merge1 the changes made in dev
onto master
git merge dev
Before pushing changes make sure that there were no changes already made, so fetch
and merge
git fetch
git merge origin/master
- N.B.: What is happening here is we pulled down the current state of the entire remote repo (
origin
) withfetch
and then merged the changes that exist in the remote branch (origin/master
) onto the branch we currently have checked out (master
)
which will result in the following merge conflict:
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
Edit the README
to resolve the conflict:
<<<<<<< HEAD
This is a local edit to the README!
=======
This is an upstream edit to the README from the web!
>>>>>>> origin/master
to
This is a local edit to the README followed by an upstream edit to the README from the web!
Then commit and push
git add README.md
git commit -m "Resolve merge conflict"
git push origin master
Edits, Diffs, and Resets
Suppose we make several commits to the README
echo "This is an edit" >> README.md
git add README.md
git commit -m "Edit 1"
echo "This is another edit" >> README.md
git add README.md
git commit -m "Edit 2"
The README
has just been put in a commit
, so if we ask the repo what is different from the current state to the repo state
git diff README.md
it returns nothing. The current state of the files are the same as the last commit to the repo. However, if we now do
echo "What has changed" >> README.md
git diff README.md
we see at the bottom the addition
This is an edit
This is another edit
+What has changed
If we now ask what has changed between this current state and the second to last commit
git diff HEAD^ -- README.md
we get
This is an edit
+This is another edit
+What has changed
and the third
git diff HEAD^^ -- README.md
gives
+This is an edit
+This is another edit
+What has changed
If we decide that we don't like the edits that we've made and we want to revert back to how the state the repo was in after the last commit then we can just checkout the HEAD
git checkout HEAD -- README.md
and we can see we are back at the last commit
git diff
If we decide we want to go back to the state before we made our three consecutive commits then we can just do
git checkout HEAD^^ -- README.md
and git diff
or cat README.md
will reveal have recovered the state of the README
before we made the edits.
-
N.B.: We have recovered the state of the
README
but we have not undone our commits. Simply checkinggit log
shows us this.Example of Matthew's daily workflow
Every directory on my local computer that has code in it is a Git repo. A typical snapshot of what that looks like is
git branch
* YYYY-MM-DD
dev
master
though if this repo has a remote then going to look at it will only show you master
and dev
.
Why?
The idea here is that master
should always be production ready and dev
should be where the new feature that I'm working on it being tested. However, each day I don't want to possibly contaminate dev
. So everyday when I start work I (from the dev
branch) do
git checkout -b YYYY-MM-DD
and then do all my work for the day in the YYYY-MM-DD
branch. Then at the end of the day I simply
git checkout dev
git merge YYYY-MM-DD
git branch -d YYYY-MM-DD
so dev reflects the day's improvements and as YYYY-MM-DD
has served its purpose it is removed.
If everything has become a raging dumpster fire (it is 2016 when I'm writing this, so there should really be a raging dumpster fire emoji2 🗑 🔥) I can instead do
git checkout dev
git branch -d YYYY-MM-DD
and walk away with no damages to try again tomorrow. :)
1) Please though, never DR;JM ↩