diff --git a/content/post/introduction_to_git.md b/content/post/introduction_to_git.md new file mode 100644 index 0000000..bfd31fb --- /dev/null +++ b/content/post/introduction_to_git.md @@ -0,0 +1,423 @@ +--- +title: "Introduction to git" +draft: false +date: 2019-10-22T19:00:00+02:00 +image: "uploads/Git-Logo-2Color.png" +tags: [GIT, training, tutorial] +categories: [Projects] +--- + +As you man now I work in a research lab. Nearly everyone in our lab needs to do at least some programming. There are trained software engineers next to people how write their first line of code here. +As we produce a lot of code that is only scripts not many people used git or any other version control system. +For all the good reasons (some are mentioned in the guide) we everybody to learn git in a way that is tradeoff between good version control and fast development. +As most of us work on separate projects there is not so much need to collaborate which is reflected ind this guide as I completely excluded branching and merge conflicts. +Yet I hope this will maybe help some learners of git or some people that need to introduce git to others. + +I will not be updating this guide, for the newest version please visit https://github.com/GerJuli/introduction-to-git + + +Now enjoy the guide! + +# Installation + +* On Windows: Download git here: https://git-scm.com/download/win and install it +* On Linux: execute 'sudo apt install git' in the terminal + +# Configuration + +## Basics + +```bash +$ git config --global user.name "John Doe" +$ git config --global user.email johndoe@example.com +``` + +Run these commands without --global to apply changes only for local repository. + +## Advanced + +* Change from default editor by executing `$ git config --global core.editor vim` +* Create aliases by: + - `git config --global alias.unstage 'reset HEAD --'`: + Introduces new command unstage + + - `git config --global alias.hist 'log --pretty=format:"%h - %an, %ar : %s" --graph'`: + Is an pretty alternative to git log. + +* Check the configuration by `$ git config --list` + +# Getting started + +## Create an directory +Select an directory of your choice e.g. ~/Desktop/git-training/, +open the terminal there and type + +```bash +$ git init +``` +Congratulations you have your first git repository! + +## Committing files +Create some text files e.g. `hallo.txt` or `hello_world.py`. +To start version-controlling them add the file to git by using the command +```bash +$ git add filename +``` +You can also add multiple files. E.g. you want to add all text files the do +```bash +$ git add *.txt +``` +Now we can commit these changes by typing +```bash +$ git commit +``` +This will open your preferred text editor +where you can type in a commit message. + +### Commit messages + +*Commit messages are important* + +Why are the so important? Because it is much easier to track bugs with it, +they describe the process of development, make it easier for others to work +with your code (e.g. code review) and will help you in two years to understand what you did. +They extend your labbook in its function. + +#### How to write commit messages +* Use present tense and use imperative +* Tell why you did changes. +* Limit yourself to 50 characters in the first line. +* Wrap the body at 72 characters + +#### Good commit messages + +For short commits that need only few explanation it is convenient to use +```bash +$ git commit -m "Fix typo in introduction to user guide" +``` + +For long commit message you use +```bash +$ git commit +``` +which opens a text editor and lets you describe your changes in detail. Do not forget the line +between header and body of the commit message. + +``` +Summarize changes in around 50 characters or less + +More detailed explanatory text, if necessary. Wrap it to about 72 +characters or so. In some contexts, the first line is treated as the +subject of the commit and the rest of the text as the body. The +blank line separating the summary from the body is critical (unless +you omit the body entirely); various tools like `log`, `shortlog` +and `rebase` can get confused if you run the two together. + +Explain the problem that this commit is solving. Focus on why you +are making this change as opposed to how (the code explains that). +Are there side effects or other unintuitive consequences of this +change? Here's the place to explain them. + +Further paragraphs come after blank lines. + + - Bullet points are okay, too + + - Typically a hyphen or asterisk is used for the bullet, preceded + by a single space, with blank lines in between, but conventions + vary here + +``` + +#### Hall of shame +Here you see some examples of bad commit messages. + +* “bug fix”, "more work”, “minor changes”: +Bad because it contains no useful information + +* “Change X constant to be 10”: +Bad as it does not tell why. What was changed is easy to find out by + git diff. + +* “super long commit message goes here, something like 100 words and lots of characters woohoo!”: +Bad because it is unreadable. + +## Storing changes on remote server +To store changes on a remote server e.g. Github you need to push your repository there. +If you are doing this for the first time you first need to define where to push your repository to. +Use + +```bash +$ git remote add origin https://github.com/GerJuli/introduction-to-git.git +``` + +The URL can be +replaced with any URL that points to an existing repository. This can even be a USB drive! +Now push by using `git push -u origin master`. With this command you created an upstream to your +remote 'origin' where you branch 'master' will be pushed. +As this is set up you can use `git push` from now on. + +# Cloning existing repositories +Downloading existing repositories is called 'cloning'. You can do this by using +```bash +$ git clone https://github.com/GerJuli/introduction-to-git.git +``` +That is it. Now you can start working on it. + +# Workflow + +## Check status +With +```bash +$ git status +``` +you can check the status of your current directory. +This will look like this: + +```bash +$ git status +On branch master +Your branch is up-to-date with 'origin/master'. +nothing to commit, working directory clean +``` + +## Add file +If you now add a file to the repository e.g. README then the status changes. + +``` bash +$ echo 'My Project' > README +$ git status +On branch master +Your branch is up-to-date with 'origin/master'. +Untracked files: + (use "git add ..." to include in what will be committed) + + README + + nothing added to commit but untracked files present (use "git add" to track) +``` + +You can also run + +```bash +$ git diff +``` + +which will show you the changes that where made. + +Now track the file by adding it to the staging area via + +``` bash +$ git add README +``` + +If you want to commit only a part of the changes you made use +```bash +git add -p +``` +git will ask you for every "hunk"(part of the file) if you want to add it to the staging area. +The main options are: + +* y stage this hunk for the next commit +* n do not stage this hunk for the next commit +* q quit; do not stage this hunk or any of the remaining hunks + +## Committing +The changes are now ready to be committed + +``` bash +$ git status +On branch master +Your branch is up-to-date with 'origin/master'. +Changes to be committed: + (use "git reset HEAD ..." to unstage) + + new file: README +``` + +Now commit this change with a suitable commit message. +You forgot what you changed and `git diff` does not work? +If you already added the file to the staging area you can run +```bash +$ git diff --staged +``` + +## Push to remote +Push this now to your repository with + +```bash +$ git push +``` + +## Show last changes + +```bash +$ git log +``` +shows you a log of recent commit messages. + +If you want to have a look at the changes source use +```bash +$ git log -p +``` +A much prettier version is +```bash +$ git log --pretty=format:"%h - %an, %ar : %s" --graph +``` + +# Get latest changes +An amazing thing of git is to work together with others. This guide will not go into the details +of this, yet you will often have to get the latest changes of a project. + +You can do this easily by using +```bash +$ git pull +``` +which is a short version of two different commands. It first executes `git fetch` that downloads +the latest changes. Then it runs `git merge FETCH_HEAD` which tries to apply the newest changes +to your local repository. This is also the difficulty of this as any file that was changed locally +and in the remote repository will cause a *merge conflict* as git does not know which file/parts +of the file to keep. The resolution of such a conflict can be complicated and goes beyond the +intentions of this guide. + +A brief overview can be found +[here](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-using-the-command-line). + +## Gitignore +Sometimes you do not want git to track every file in your repository. +Typically this applies for log files, configuration files (where maybe passwords are stored) +and compiled sources. For this purpose you can create the file `.gitignore` in your repository. +This file will be read by git. An example `.gitignore` looks like this: + +```gitignore +# ignore all .log files +*.log + +# ignore all files in any directory named config +build/ + +# but do track sample.log, even though you're ignoring .log files above +!sample.log + +# only ignore the TODO file in the current directory, not subdir/TODO +/TODO + +# ignore all files in any directory named build +build/ +``` +You can generate gitignore files [here](https://www.gitignore.io/). + +# Undoing things + +## Make changes to the last commit +You forgot to add one file to your commit? +You are unhappy with your commit message? +Use `git --amend`! +```bash +$ git commit -m 'Pretty commit message' +$ git add forgotten_file +$ git commit --amend +``` +Do not do this if you already pushed to remote. + +## Unmodifying a Modified File +You made changes to a file but the changes messed everything up? +You can always go back to the version of the last commit by +```bash +git checkout -- filename + +``` +*Warning*: This is dangerous as you delete all changes that you made locally. +Do NOT use this command unless you are absolutely sure what you are doing. + +## Time machine +Something went terribly wrong. When using git this is no problem. +Just use `reflog` and select the commit where still everything was alright. + +```bash +$ git reflog +9bff138 HEAD@{0}: commit: Document limitations of this guide +8d9dac8 HEAD@{1}: commit (amend): Adjust script to nice print +[...] +2b66f53 HEAD@{7}: commit: Introduce git log +8835c33 HEAD@{8}: commit: Fix of formating of headings +2f0f500 HEAD@{9}: commit: Improve order of comments on workflow +249dc14 HEAD@{10}: commit (amend): Explain git diff +f5ba1d3 HEAD@{11}: commit: Explain git diff +0a2ce1c HEAD@{12}: commit: Remove trailing whitspaces +735511f HEAD@{13}: commit (initial): Initial commit + +$ git reset HEAD@{index_where_everything_was_fine} +$ git reset --hard origin/master +``` + +*Warning*: This is dangerous as you delete all changes that you made locally. +Do NOT use this command unless you are absolutely sure what you are doing. + +# USB sticks as remote +Sometimes (e.g. you are working on a machine that is not connected to the internet) it can be +helpful to use an USB drive as remote. + +## How to prepare the drive + +Go to the USB drive +```bash +$ cd /media/username/git-stick/ +``` +Create a directory for your repository +```bash +$ mkdir my-repo +``` +Initialize the repo +```bash +$ cd my-repo +$ git init --bare +``` + +## How to push to a USB drive + +To push to a USB drive you need to add a remote. Go to your local repository and use +```bash +$ git remote add usb /media/username/git-stick/my-repo/ +``` +Be aware that your stick will have a different name and will be at a different location, depending +on your operating system. You named the remote "usb" here, of course you can change that name. + +Now push your repo +```bash +$ git push usb +``` + +To list all repositories just type +```bash +$ git remote +origin +usb +``` + +If you want to push to the USB drive by default you can use +```bash +$ git push -u usb master +Branch 'master' set up to track remote branch 'master' from 'usb' +``` + +# What this guide does not cover + +* Branching + - Creating branches + - Merging branches (and merge conflicts) + - Remote branches + - Tagging + - Forks +* Usage of Github +* Hooks + +# Further reading + +* Official git website [Git SCM](https://git-scm.com/): Extensiv documentation +* [Oh shit Git](https://ohshitgit.com/): Help when you messed up. + + + + +# Logo +Git Logo by Jason Long diff --git a/static/uploads/Git-Logo-2Color.png b/static/uploads/Git-Logo-2Color.png new file mode 100644 index 0000000..51f4ae5 Binary files /dev/null and b/static/uploads/Git-Logo-2Color.png differ