git training
TRANSCRIPT
![Page 1: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/1.jpg)
Advanced GIT Conceptsby Eric Aguayo (a.k.a. ericmaster)
![Page 2: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/2.jpg)
BASIC CONCEPTS
What is GIT?● DVCS
GIT Architecture● Working Copy● Staging Index (a.k.a. index)● Local Repository (a.k.a. repo or repository)● Remote Repository (a.k.a. remote)
![Page 3: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/3.jpg)
GIT Architecture
REMOTE SERVER
LOCAL MACHINE
WORKING COPY
DEV MACHINE
REPO
INDEX
DEV MACHINE
ORIGIN
DEV2
DEV1
DEV3
REMOTE MERGE
![Page 4: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/4.jpg)
GIT Architecture
Source: http://geeks.ms/blogs/etomas/archive/2011/01/18/git-para-dummies-pero-dummies-dummies-eh.aspx
![Page 5: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/5.jpg)
GIT ARCHITECTURE
WORKING COPY
INDEX: works as a staging area between working copy and repo
REPOGIT Objects
● blob: stores the data● tree: reference other trees and
blobs (directories)● commit: references to a tree
and contains all the info of a commit
● tag: mark a reference to a specific object
git addgit commit
![Page 6: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/6.jpg)
.git Directory File Structure
Contains all the information to recreate the tree history
|-- HEAD (pointer to the current branch)|-- config (holds the configuration preferences)|-- description (description of your project)|-- hooks/ (pre/post action hooks)|-- index (contains the index of the repo)|-- logs/ (a history of where the branches have been)|-- objects/ (the objects (commits, trees, blobs, tags)`-- refs/ (reference to important commit objects)
![Page 7: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/7.jpg)
GIT most common commands
init: Initialize a repository, initialize it empty with the --bare option or based on existing contentbranch: Creates a new branch/Show all branchesclone: Initialize a repository and working directory from a remote repositorycheckout: This has several purposes: Change branch or revert a file or directorystash: Temporarily saves the changes and wipe those changes from the index and working copy
![Page 8: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/8.jpg)
GIT most common commands
status: Displays informational data about the local repository, files added to the index and current branchadd: Adds changes to the staging indexcommit: Record changes into the local repositoryrebase: Used to edit commits or join commits into a single commit to cleanup tree history
![Page 9: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/9.jpg)
GIT most common commands
fetch: Get commits from a remote (this does not merge the commits or apply the commits to working copy)merge: Merge the commits of a branch on a remotecherry-pick: Merge a specific commit from a remotepull: Merge the changes from the origin repository on the current branchpush: Push changes to a remote repository
![Page 10: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/10.jpg)
GIT most common commands
rm: Deletes a file from the staging index (not deletes the physical file by itself)reset: Remove file from index or Reset (Rollback) HEAD to a specific commitrevert: Revertir un commit (not a file)diff: Shows differences between commits or branchesshow: Shows commit details (user, time and changes)log: Shows commit history
![Page 11: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/11.jpg)
GIT Configuration
git-config: Used to configure repository settings (/git/config file) or global settings (.gitconfig). For example:
git config --global user.name "Username"
will get the following result into .gitconfig file generally located in your home directory
[user]...name = Username...
![Page 12: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/12.jpg)
Git ConfigurationThese are the basic settings that every developer should set in their local environments:
git config --global user.name "Username"
git config --global user.email "[email protected]"
Also these are useful commands that will display output of some commands in a better way
git config --global color.branch autogit config --global color.diff autogit config --global color.interactive autogit config --global color.status auto
git config --global format.pretty oneline
![Page 13: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/13.jpg)
GIT Configuration
In a similar way we can set a specific repository configuration. For example, to set the remote origin as the default remote for the branch master
git config branch.master.remote origin
will get the following result into .git/config file
[branch "master"]...remote = origin...
![Page 14: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/14.jpg)
Create a new repository
We can create a new repository from any directory where we have write permissions. It is as simple as running the command
git init
In general, the origin or any repo that you want to make public must be a bare repository, in which case we will run
git init --bare
![Page 15: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/15.jpg)
Clone a existing repository
GIT supports different protocols to clone. Here are some examples:
git clone [email protected]:ericmaster/liquidsoap
git clone file://localhost/srv/git/liquidsoap
git clone ssh://[email protected]/srv/git/liquidsoap
The first approach we will tipically use to clone from a public repository. Second approach we will tipically use to clone from a local machine. Third approach we will tipically use to clone a repo from a server where we have an account set up.
![Page 16: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/16.jpg)
GIT Workflow
A tipical workflow of a git repository involves the following commands
git diff (see what is about to be commited)
git add file1 file2 file3 (adding files to the index)
git status (verify all files have been included in the staging index)
git commit -m 'some message about this commit' (record commit in the repository)
You may skip "git add" if you want to add all modified files (not new created files) by running:
git commit -a -m 'some message about this commit'
![Page 17: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/17.jpg)
Checking the status
This is the info that we may get when we run the "git status" command:This line will tell us in which branch we are#On branch development
This line will tell us that the current branch has 12 more commit objects than what it has in its origin.#Your branch is ahead of 'origin/development' by 12 commits.
After push to the origin git status will basically say that everything is ok by the following output:#nothing to commit (working directory clean)
This line will tell us that the branch at the origin branch has 10 more commit objects than what is in the current branch, this may indicate that we need to pull to update our working copy#Your branch is behind of 'origin/development' by 10 commits.
In many cases we will have the following output:#Your branch and 'origin/development' have diverged,
#and have 14 and 30 different commit(s) each, respectively.
This tells us that there are 14 commit objects in the current branch in your local repository that have not been pushed yet and 30 commit objects in the same branch at its origin that has not been pulled yet.
![Page 18: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/18.jpg)
Checking the statusThese lines will tell us which files have been added to the index# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)## modified: file1
These lines will tell us which files have been modified but not added to the index# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)## modified: file1
These lines will tell us that there are files that are not under tracking# Untracked files:
# (use "git add <file>..." to include in what will be committed)## filex
![Page 19: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/19.jpg)
Working with branchesSuppose that you have been assigned a task to create a new user profile page. You can create a separate branch for this new feature by using:
git branch feature_user_profile
To list all branches use
git branch (to list all branches in the current repository)
git branch -a (to list all branches including branches in tracked remotes)
Output of the first command should be
feature_user_profile
master*
* Indicates our current branch
![Page 20: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/20.jpg)
Working with branchesBesides using checkout to discard changes of a file you can use it to switch branches
git checkout feature_user_profile
Now you can make some modifications to your working copy, add those changes to the index and commit, then switch back to the master branch. You will notice that any change you make on feature_user_profile branch will not affect the master branch. Once we are done with the feature we can merge those changes back to the master branch (make sure your current branch is the master branch).
git merge feature_user_profile
git cherry-pick commit_id (in case you just need to merge a specific commit)
![Page 21: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/21.jpg)
Working with remotes
In a real case, you will have to work in a feature with multiple developers (each with its own working copy). At some point you will need to synchronize your code with the rest of the developers. You could push your code to the origin so others can pull but we do not want to do that because other developers' code might be affected by a work in progress, specially if you are pushing to the "master" branch or the main branch of development.
So you will need to track each developer repository as a remote. To do this you need to add the remote into your config.
ORIGIN
DEV1 DEV2 DEV3
ORIGIN
DEV1 DEV2 DEV3
AVOID
![Page 22: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/22.jpg)
Working with remotesFirst we add the remote with the following command (typically we will identify each remote by the owners name or a nickname easy enough to remember in this case the remote name will be "developer2")
git remote add developer2 ssh://[email protected]/home/developer2/
git config remote.developer1.fetch +refs/heads/*:refs/remotes/developer2/*
which will add the following entry in the .git/config file. First line adds the remote and assigns a url so we can know where it is. Second line allows us to track the heads of the different branches of the remote.
[remote "developer2"]
url = ssh://[email protected]/home/developer2/
fetch = +refs/heads/*:refs/remotes/developer2/*
![Page 23: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/23.jpg)
Working with RemotesNow we have everything we need to merge changes with a remote repository. First we need to get all the commit objects from the remote repo into our local repo with the following command:
git fetch developer2
git fetch --all (if you want to get all the commit objects from all the remotes you are tracking)
Next thing we want to do is to merge the changes into our working copy, for this we can use the merge command
git merge developer2/feature_user_profile
git pull developer2/feature_user_profile (actually git pull is a shorthand for git fetch and git merge)
If everything goes right, we should see a message telling us how many files were changed and how many line insertions/deletions were made35 files changed, 2334 insertions(+), 309 deletions(-)
![Page 24: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/24.jpg)
Dealing with conflictsAt some point you will have to deal with conflicts when you get a message like this after running a pull or merge command
CONFLICT (content): Merge conflict in file.txtAutomatic merge failed; fix conflicts and then commit the result.
There are many ways you can deal with conflicts, as well as there are many tools that will help you to deal with this. When a conflict occurs, your local repo will not be updated and the index will be left in a special state until you resolve the conflict and push the changes. If you run git status you will see that successfully merged files are already added to the staging index ready to be committed while conflicted files will show as
# both modified: file.txt
Both modified means that there are modifications of the file in your local branch as well as the remote branch that could not be automatically merged
![Page 25: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/25.jpg)
Dealing with conflictsTo resolve conflicts you need to edit the file and look for the following tags
<<<< HEAD
//Here goes the local code
====
//Here goes the incoming remote code
>>>> commit_id
There are some tools like merge-tool which can be integrated with git command line that will display in a split screen showing the local code in the left and the remote code in the right. You can also look at the conflicts with:
git diff file.txt
Clarity and good documentation of the code are determining factors in the process of resolving a commit.
![Page 26: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/26.jpg)
Dealing with conflictsMany times you will be able to resolve the conflicts by simple inspection of the code. For example, the HEAD of your branch might have a condition like this
if(c1 && c2){...}
while the remote commit might have something like
if(c1 && c3){...}
most likely is that this commit could be solved, depending on the case, by changing the conflicted piece to
if(c1 && c2 && c3){...} orif(c1 && c2 || c1 && c3){...}
![Page 27: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/27.jpg)
If the case is more complex, you can run the following command get the commit details including the author and its descriptive message and take some decision based on that:
git show commit_id
Sometimes, if we cannot solve the conflict by ourselves we can contact the developer author of the commit to get some more information that might help us to resolve the conflict. We might even decide that is better to keep "our" or "their" modifications only. In the first case we will use the following command:
git checkout --ours file.txt
otherwise we can keep their changes
git checkout --theirs file.txt
Dealing with conflicts
![Page 28: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/28.jpg)
Dealing with conflictsAfter you have resolved the conflict, you need to add the resolved file to the staging index and commit.
In the case you get stuck with the conflict and just decide to get back to the state before the merge you can use the following command
git reset --hard HEAD
but if you already commited the merge you can use
git reset --hard ORIG_HEAD
when we add the --hard option we are discarding any changes made to index (not the working directory) while --soft option leaves the index intact
![Page 29: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/29.jpg)
Checking the commit historyWhenever you find a problem or want to check for a code that was removed some time ago, you can always check the logs to see the commit history in the current branch:
git log
git log file.txt (to check the log for a specific file)
The git log command has many options to output the data you need in a better way. Check the documentation for a better explanantion of these options http://schacon.github.com/git/git-log.html.
You can also find which user edited a specific line of a file through the following command
git blame
![Page 30: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/30.jpg)
Creating aliasesThere are common aliases used in git repositories. For example I can add a shorthand for checkout with
git config --global alias.co checkout
Also there are other common aliases that are very useful. You can add them through the git config command or write them directly into .gitconfig file
[alias] co = checkout ci = commit st = status br = branch hist = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short type = cat-file -t dump = cat-file -p
![Page 31: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/31.jpg)
Creating Tags
The git tag command creates a static branch that we can refer later (or revert if necessary)
git tag -a v1.2 -m 'version 1.2'
To display the tags just type
git tag
![Page 32: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/32.jpg)
Ignoring FilesIn most of projects there are special files, typically configuration files or content files that are specific to the local working copy where they exists. We do not want to track these files through git. To prevent these to show up in the staging index just add the file names to a special file named .gitignore. This special file will typically look like this:
# Ignore any file named foo.txt.foo.txt# Ignore (generated) html files,*.html# except foo.html which is maintained by hand.!foo.html# Ignore objects and archives.*.[oa]
If you are already tracking a file through git you can remove it by running the following command and the commit
# git rm --cached foo.txt
![Page 33: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/33.jpg)
Rebasinggit rebase can be used to cleanup the branches tree history. Instead of merging your main development branch into your current feature work branch you rebase the development branch:
git rebase development
git rebase -i development (to interactively add commits)
which will discard your commit(s) and reapply them as patches after the HEAD of the development branch. If in any case you get a conflict, use the following command after resolving the conflict
git rebase --continue
also you may cancel the rebase process by
git rebase --abort
![Page 34: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/34.jpg)
Stashing changesIn any project, you may often want to pull to update your working copy but do not want to commit your code yet. Git will not let you pull if the incoming commit(s) belongs to a file that you are editing. In this case you can temporarily save your changes and "revert" to the HEAD of your repo with the following command
git stash
This is also useful if you need to perform a quick fix without needing to commit or discard the changes of your current task, or even create a new branch. Once you are done with the changes, just run the following command to get your save changes back
git stash pop
![Page 35: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/35.jpg)
Hooks
GIT allows you to implement hooks to execute certain events occur in your repo. For example you might need to change some setting files in your working directory before you switch to another branch. This can be implemented in a hook.
Under the .git/hooks directory you can find files that you can edit to perform processing on determined events. For example you can use the file
.git/hooks/post-commit
to notify to some system that a commit was made
![Page 36: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/36.jpg)
GIT ToolsSet up public repositories● gitosis● gitolite (recommended by the community, see http://www.llamabyte.
com/2011/upgrading-to-gitolite-from-gitosis/ for advantages)
Merge tools:● Open Source
○ kdiff3○ tkdiff○ xxdiff
● Free from a commercial vendor○ SourceGear DiffMerge○ FileMerge/opendiff○ Perforce Visual Merge Tool (P4Merge)
● Commercial○ Araxis Merge (Windows | Mac OS X)○ Beyond Compare○ Guiffy SureMerge
![Page 37: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/37.jpg)
Common issuesI deleted a file how to commit that change to my local repo?
There are two options:
git add -A .
git commit -m
or
git commit -a -m.
Note: git commit -a -m does NOT add new created files to the staging index
![Page 38: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/38.jpg)
Common issuesI made a commit but I want to correct the message or forgot to add my username or email
To correct the message of the last commit use:
git commit --amend -m 'correct message'
To correct the message of commit previous to the HEAD commit you can use:
git rebase -i commit_id^
then change "pick" to "edit" in the interactive mode for commit_id, make the changes and then rungit commit --amend
git rebase continue
![Page 39: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/39.jpg)
Common issues
I need to revert a commit given by a specific commit_id
Just run the following command
git revert commit_id
this will revert the commit object and commit the revert. Add the --no-commit option to leave the changes in the staging index for any further modification before commit
Note: this might lead to conflicts if the subsequent commits have overlapped changes.
![Page 40: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/40.jpg)
Common issuesI need to work in team with a developer who created a new branch for a specific feature. How do I clone that branch over my current working copy?
After adding the remote "developer", just run the following command
git checkout --track -b new_feature developer/new_feature
this will create the new repo and add the necessary branch settings in the .git/config file
![Page 41: Git training](https://reader035.vdocument.in/reader035/viewer/2022081403/5549a176b4c9050c738b4ed2/html5/thumbnails/41.jpg)
GIT Workshop
ssh://[email protected]/srv/gitworkshop/not_bare_repo
ssh://[email protected]/srv/gitworkshop/repo