Skip to content

Instantly share code, notes, and snippets.

@Mavlarn
Created November 29, 2013 05:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mavlarn/7701999 to your computer and use it in GitHub Desktop.
Save Mavlarn/7701999 to your computer and use it in GitHub Desktop.
git tutorial
# Git tutorial #
This tutorial will show you some basic usgae of git, including how to create a git repository, commit, push to local and remote repository. And also show you how to use with more than one remote repository,
## Working in local repository ##
-------
At first, we will create a git repository in our local and working on that. We will create a project with git and add/modify some files.
At first, create a repository:
```bash
mkdir test_proj
cd test_proj
git init
> Initialized empty Git repository in /Users/mavlarn/tmp/test_proj/.git/
ll -a
total 0
drwxr-xr-x 3 mavlarn staff 102 11 29 10:57 .
drwxr-xr-x 3 mavlarn staff 102 11 29 10:57 ..
drwxr-xr-x 9 mavlarn staff 306 11 29 10:57 .git
```
The repository for my project is created. Now we can copy th existing project into this directory, or working on this directory from empty.
For demonstration, I created some files here:
```bash
echo text1111 > 1.txt
echo text2222 > 2.txt
echo text3333 > 3.txt
```
Now there are 3 files in my project. I can check the repository status.
```bash
git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# 1.txt
# 2.txt
# 3.txt
```
As it said, I need to add these new files into my local repository.
```bash
git add .
git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: 1.txt
# new file: 2.txt
# new file: 3.txt
```
"." in "git add ." means "all".
Now they are ready to commit.
```bash
git commit -m "init commit"
[master (root-commit) 0a0738c] init commit
3 files changed, 3 insertions(+)
create mode 100644 > 1.txt
create mode 100644 > 2.txt
create mode 100644 > 3.txt
```
-m is used to add commit message.
Now we will modify some files.
```bash
rm 1.txt
echo "text1 new content" > 1.txt
echo "text44444 content" > 4.txt
```
> **Notice** that I removed 1.txt file and created again.
And check the status:
```bash
git status
# On branch master
# 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: 1.txt
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# 4.txt
```
> You can see the message "Changes not staged for commit". It means the file "1.txt" in not in stage, should be added with "git add". Becasue I deleted it and created again.
Then we can see the difference with (maybe you will see some different result):
```bash
git diff
diff --git a/1.txt b/1.txt
index b070acd..a2d9f05 100644
--- a/1.txt
+++ b/1.txt
@@ -1 +1 @@
-text11111
+text1 new content
```
With "git diff", we can see the modified content of "1.txt". (Even it is recreated.) But it didn't include the new added file. Because we haven't added it into git index yet.
Now we add new file and remove another file.
```bash
git add 4.txt
git rm 2.txt
git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: 2.txt
# new file: 4.txt
#
# 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: 1.txt
```
At last, we will commit the changes.
```bash
git commit -m "new message"
[master 0fe6c38] new message
2 files changed, 1 insertion(+), 1 deletion(-)
delete mode 100644 2.txt
create mode 100644 4.txt
```
Check the status again:
```bash
git status
# On branch master
# 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: 1.txt
```
We didn't add 1.txt yet. (Because we recreated it.) Add it again and commit.
```bash
git add 1.txt
git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: 1.txt
git commit -m "update 1.txt file."
```
For the commit history, you can check with:
```bash
git log
commit 0fe6c38e5721b0f72f14c4e3ec899fa8b93ebabc
Author: Mavlarn <mavlarn@gmail.com>
Date: Fri Nov 29 11:19:54 2013 +0800
new message
commit 0a0738c4db3437b0c67c804cd01c2eaf56a2715f
Author: Mavlarn <mavlarn@gmail.com>
Date: Fri Nov 29 11:09:38 2013 +0800
init commit
```
## Git working flow ##
We did some work with git above. And let me explain some concepts and working flow in git with the char below:
![Git Local][1]
There are 3 phases for all files in local git repository:
- workspace
- staging/index
- repository
Staging/index, is the status in the middle, means the files will be tracked by git, but it is not added into version yet.
For the file in staging phase, they have only one "current" status, and there is no history. After you commit them into your repository, they will be marked as versioned. Then you can track the version and difference.
Now you have your project under version control with git. If you just work with yourself, and don't need to create a backup for your repository, it will be enough.
## Working With Remote Repository ##
--------
Git is a **distributed** version control tools. It's meaning is, for every one who is using git, they have already had a version control tool in their local machine. Every one can use them to track the version and difference, create/merge branches, create tags, etc.
Moreover, you can let your local repository to communicate with others. You can push your files into some other's repository, or pull from other's repository. When you push from other's repository, you can even get their version info.
Now, let's add a remote repository for our project.
Before that, we need to create a repository in some remote machine. Assume that we are working one a remote machine. I will create a repository.
```bash
-bash-4.1$ mkdir test_proj
-bash-4.1$ cd test_proj
-bash-4.1$ git init
> Initialized empty Git repository in /home1/irteamsu/mavlarn/test_proj/.git/
```
Now, come back you our local machine, and add the remote repository for our local repository.
```bash
git remote add origin irteamsu@10.101.60.69:~/test/test_proj
git remote -v
origin 10.101.60.69:~/test/test_proj (fetch)
origin 10.101.60.69:~/test/test_proj (push)
```
We use "git remote add" to add a remote repository. The "origin" is the name of this remote repository. "origin" is the default name for most of the git system. And, of course, you can use some other. You can also set several remote repositories.
> **Notice**
Pleace be carefule about the remote git url. I use **"irteamsu@10.101.60.69:~/test/test_proj"**. It is just a normal remote path which we use with ssh. If the current user in you local machine is same as the user in remote machine, you can skip the user "irteamsu".
"-v" option is used to list the remote repositories.
If you want to remove some, you can also remove with:
```
git remote rm remote_repos_name
```
If you want to modify one remote url, you can also change it:
```bash
git remote set-url origin irteamsu@10.101.60.69:~/*other_dir*/test_proj
```
Now, let's try to push our files into this remote repository. We will push with a remote name and branch. It means, we will push our files and version info into the remote "origin" repository, and into "master" branch.
```bash
git push origin master
irteamsu@10.101.60.69's password:
Counting objects: 8, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (8/8), 571 bytes | 0 bytes/s, done.
Total 8 (delta 0), reused 0 (delta 0)
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To irteamsu@10.101.60.69:~/test/test_proj
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'irteamsu@10.101.60.69:~/test/test_proj'
```
There should be some error like that if you follow this tutorial. The reason is, in remote repository, it's current working branch is "master", if you push your file into other's current working branch, you will directly update your files into other's working files. If some other is working on this remote machine and editing something in these files, this push operation will cause some conflicts.
This error message is actually a warning, to tell you you can not do that by default.
So, you have 2 options here:
1. Let the remote repository in other branch and push.
2. Add a configuration to ignore this.
In our scenario, the remote repository will be used as some kind of center repository. All of the project members will push their files into that repository. And no one will working on that repository locally. So, we will choose the second option to ignore:
```bash
git config receive.denyCurrentBranch ignore
```
Then we push again:
```bash
git push origin master
irteamsu@10.101.60.69's password:
Counting objects: 8, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (8/8), 571 bytes | 0 bytes/s, done.
Total 8 (delta 0), reused 0 (delta 0)
To irteamsu@10.101.60.69:~/test/test_proj
* [new branch] master -> master
```
The push process is like "compress all necessary files, diff content, version related content into a compressed object and copy into remote repository with ssh."
Now, you can see that all version info in our local has been updated into **remote** repository:
```bash
-bash-4.1$ git log
commit 0fe6c38e5721b0f72f14c4e3ec899fa8b93ebabc
Author: Mavlarn <mavlarn@gmail.com>
Date: Fri Nov 29 11:19:54 2013 +0800
new message
commit 0a0738c4db3437b0c67c804cd01c2eaf56a2715f
Author: Mavlarn <mavlarn@gmail.com>
Date: Fri Nov 29 11:09:38 2013 +0800
init commit
```
##Work Flow With Remote Repository##
--------
We have explained how git is distributed tool to control version. So, when we working with remote repository, what we did is just get/set the version info between local and remote repository.
The char in below show the working flow with remote repository.
![enter image description here][2]
##Git Branch##
TBC.
> Written with [StackEdit](https://stackedit.io/).
[1]: http://artical-pics.u.qiniudn.com/git-local.png
[2]: http://artical-pics.u.qiniudn.com/git-remote.png
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment