GitManual
GitManual copied to clipboard
Git instruction manual and related resources
Git Manual
Here is a small Git guide. Created to learn command line git instructions, rather than using GUI tools like SourceTree. There are only some basic and some interesting stuff we could use in our day to day codibg. Enjoy!
Sources worth to check
Blogs
Courses
Table of Contents
- Repository initialization
- Branches
- Find bug navigationg through commits
- Git ignore
- Global
- Android
- IntelliJ
- Mac OS
- Windows
- Tips
Locally
# Inside the project folder
$ touch README.md
$ git init
$ git add README.md
# Outside the project folder
$ git init <directory>
# START HERE if you have already your project initialized
$ git add -A .
$ git commit -m COMMIT
$ git remote add origin <repo> # Where <repo> could be ssh://[email protected]/path/to/my-project.git
From a cloud repository
$ git clone <repo> # Where <repo> could be ssh://[email protected]/path/to/my-project.git
$ git clone <repo> <directory> # Clone the repository located at <repo> into the folder called <directory> on the local machine
If we want to add a .gitignore to already initialized repo, we should do
$ git rm -r --cached . // This removes everything from the index
$ git add .
$ git commit -m ".gitignore is now working"
### Branches
### Find bug navigationg through commits
Using git bisect is a good idea. Is a tool that allows you to find an offending commit. Let’s say you’ve come across a bug in your codebase and you’re unsure of when it was introduced. If you can find a commit where the code works properly and a commit where it doesn’t, you don’t have to trace down the offending commit by hand (find a particular regression).
Imagine we have the following history
rev1 -- rev2 -- rev3 -- rev4 -- rev5 -- currentRev
We know that our program is not working properly at the currentRev revision, and that it was working at the revision rev1. So the regression was introduced in one of the commits, rev2, rev3, rev4, rev5, currentRev.
git bisect does a binary search. At each step it tries to reduce the number of revisiones that are potentially bad by half.
You can use the command the following way:
$ git stash save
$ git bisect start
$ git bisect bad
That will mark HEAD as a bad commit. Alternatively, you could pass the sha of a specific commit like so:
$ git bisect bad <sha>
Then you'll to set a good commit. This will be the last known good commit. These two commands will set the outer bounds of the binary search. After:
$ git bisect good rev1
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[< ... sha ... >] rev3
Git will split the revisions and load the first guess. In our case, it'll be commit rev3. You need to build your program, and check whether or not the regression is present. You'll also need to tell git the status of this revision with either git bisect bad if the regression is present, or git bisect good if it is not.
Let's suppose that the regression was introduced in commit rev4. Then the regression is not present in this revision, and we tell it to git.
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[< ... sha ... >] rev5
It will then checkout commit rev5. We need to check if regression is present:
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[< ... sha ... >] rev4
We test the last revision, rev4. And since it is the one that introduced the regression, we tell it to git:
$ git bisect bad
< ... sha ... > is the first bad commit
< ... commit message ... >
Over a larger range of commits this saving will be, obviously, greater. (1 + log2 N).
More info:
### Git ignore #### Global
Set a .gitignore file to apply across all projects on your local machine with:
$ git config --global core.excludesfile ~/.gitignore
It can be useful to ignore files in each project you work on but not every of your teammates on the project necessary need them.
#### Android ```sh # built application files *.apk *.ap_
files for the dex VM
*.dex
Java class files
*.class
generated files
bin/ gen/
Local configuration file (sdk path, etc)
local.properties project.properties *.DS_Store tmp
Proguard folder generated by Eclipse
proguard/
Android studio
.idea/ *.iml
Intellij project files
*.ipr *.iws *.idea */target
#Gradle build/ .gradle/
#Maven target release.properties pom.xml.*
<br>
<a name="intellij">
#### InbtelliJ
```sh
*.iml
*.ipr
*.iws
.idea/
#### Mac OS
.DS_Store
.AppleDouble
.LSOverride
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
#### Windows
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
### Tips
Use .gitconfig to save some important changes and aliases
The first time you push a git branch to a remote, you have to be explicit the first time:
$ git push origin my-branch-name
Every time after that, a simple git push will work fine. But there’s a setting for .gitconfig that will let you just push without needing that initial explicitness:
[push]
# Push current branch even if you've never pushed it before
default = current
We can also play with commit messages automation, setting a template using .gitmessage.
[commit]
template = ~/.gitmessage
Then create the template using * for gaps.
Commit Title
Related issue:
*
Related feature:
*
There are other options worth se checking:
[core]
excludesfile = /Users/user/.gitignore_global
[difftool "sourcetree"]
cmd = opendiff \"$LOCAL\" \"$REMOTE\"
path =
[mergetool "sourcetree"]
cmd = /Applications/SourceTree.app/Contents/Resources/opendiff-w.sh \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$MERGED\"
trustExitCode = true
[user]
name = User
email = [email protected]
[filter "lfs"]
clean = git-lfs clean %f
smudge = git-lfs smudge %f
required = true
git mergetool -t meld
Normal merge conflict for 'README': {local}: modified {remote}: modified
Hit return to start merge resolution tool (meld): You would then see:
Configure Git For Your Mergetool Of Choice
To configure git to remember which merge tool you want, type git config –global merge.tool [tool]. For example, if you want git mergetool to automatically use kdiff3 as our mergetool, we would type:
$ git config --global merge.tool kdiff3
ADD A REMOTE (original copy from the project)
You probably have a "remote" for each repository. You need to pull from the one remote and push to the other.
If you originally cloned from your fork, that remote will be called "origin". If you haven't added it already, you'll need to add the first guy's repository as another remote:
git remote add firstguy git://github.com/firstguy/repo.git After that's all set up, you should indeed be able to
git pull firstguy master git push origin
OR
git fetch upstream git checkout master
Merge the changes from upstream/master into your local master branch. This brings your fork's master branch into sync with the upstream repository, without losing your local changes. git merge upstream/master
Work flow
Your local repository is composed by three "trees", managed by git. The first one is your "Working folder" that contains all files. The second one is the "Index" which plays a middle area rol, and finally "HEAD" wich points to last commit released

Basic actions
We can propose changes to "Index" using
git add FILE_NAME
or
git add *
After that, we can commit our changes
git commit -m COMMIT
Now the file is included in HEAD, but it's not in the repository yet. To send data to repository execute
git push REMOTE BRANCH
To refresh your local repository to newest commit, execute
git pull
To merge another branch to your current active branch (for example master), do
git merge BRANCH
If there are conflicts, you have to solve them manually edditing thos files. After that, you should check them as merged, with
git add FILENAME
Before merging changes, you could also review them using
git diff SOURCE_BRANCH TARGET_BRANCH
If we want to fetch data and merge after that, we could use
git pull --rebase
Tags
It's recommended to create tags for every software published version, using
git tag 1.0.0 * COMMIT_ID * //where *COMMIT_ID* is 10 chars of the commit id which you want to refer with your tag, for example 1b2e1d63ff
You can get commit id with the following instruction
git log
Replace local changes
You can replace local changes using
git checkout -- FILENAME
This command replace changes in your current folder with the last work of HEAD. Both changes and files already added to Index will be without changes. If you want to undo local changes and commits, you can bring las server version and point to your main copy
git fetch origin
git reset --hard origin/master
Useful data
UI by default
gitk
Special colors for console
git config color.ui true
Show only a line for every commit in the trace
git config format.pretty oneline
Add files in interactive way
git add -i
Examples
Example 1
git commit
git commit
git checkout -b bugFix C1
git commit
git commit
git merge master
git checkout master
git commit
git commit

git rebase bugFix
git commit
Example 2
Description We want the commits to all be in sequential order. So this means that our final tree should have C7' at the bottom, C6' above that, etc etc, etc all in order
git commit
git checkout -b bugFix C1
git commit
git checkout -b side C0
git commit
git commit
git commit
git checkout -b another C5
git commit
git checkout master

Solution
git checkout bugFix
git rebase master

git checkout side
git rebase bugFix
git checkout another
git rebase side
git rebase another master

This manual could not be possible withou the help of the following pages: