關于git,之前總是遇到什么問題然后做了一個簡單總結。今天決定來一個系統的總結,加深一下自己對git的理解。
1、安裝git
這個沒有什么好說的,直接去官網下載安裝就可以了。安裝之后進行配置:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
- config:配置 --global:全局 表示這個電腦上的所有倉庫都會使用這個配置。
2、創建版本庫
執行git init
,就可以了:
$ git init
Initialized empty Git repository in C:/Users/劉歡/Desktop/gittest/.git/
- Initialized empty Git repository就是告訴我們已經在本地初始化了一個本地倉庫。initialzed---init
看到.git
目錄,就說明初始化成功。
2.1、git add .
添加文件到暫存區
我們新建一個txt文件來測試,注意不要使用Windows自帶的記事本,因為它保存UTF-8編碼文件時,在開頭添加了十六進制的字符,可能會遇到問題。這里用sublime來寫的txt文件。
值得注意的是,應該建到我們初始化git的這個目錄,有點廢話這句。
txt內容:
git is a version control system
magicliu is a handsome man
然后執行git add magicliu.txt將文件提交到暫存區。
暫存區這個東西是git借鑒了svn的有點而存在的,因為我們可能一次修改了很多文件,然后一個一個提交備注會十分麻煩,我們可以將一天修改的都提交到暫存區,然后到下班的時候將暫存區的東西以一天為時間點,
git commit -m "備注信息"
提交到倉庫。就會方便很多。也就是說我們可以多次add,然后執行一個commit.
2.2、git commit -m "備注信息"
將文件從暫存區提交到本地倉庫
$ git commit -m "a new fil"
[master (root-commit) 36cd309] a new file
1 file changed, 2 insertions(+)
create mode 100644 magicliu.txt
這樣就從暫存區提交到了本地倉庫。
3、修改文件管理
現在修改了maciliu.txt
:
git is a version control system
magicliu is a handsome cool man
運行git status
查看一下狀態:
$ 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: magicliu.txt
no changes added to commit (use "git add" and/or "git commit -a")
- modified:改正的,修正的;提示我們修改了
magicliu.txt
。
那么怎么看修改了什么呢?git diff
就可以了,顧名思義diff就是difference的意思。
$ git diff
diff --git a/magicliu.txt b/magicliu.txt
index 274ea95..4d53871 100644
--- a/magicliu.txt
+++ b/magicliu.txt
@@ -1,2 +1,2 @@
git is a version control system
-magicliu is a handsome man
\ No newline at end of file
+magicliu is a handsome cool man
\ No newline at end of file
這樣就可以看到magicliu is a handsome man被修改為了magicliu is a handsome cool man。
git add magicliu.txt
,之后git status
查看一下狀態:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: magicliu.txt
可以看到修改的文件為maciliu.txt,還提示了git reset HEAD
去返回上一階段。然后就是git commit 提交代碼:
$ git commit -m "add cool"
[master c73247b] add cool
1 file changed, 1 insertion(+), 1 deletion(-)
現在在用git status
查看一下狀態:
$ git status
On branch master
nothing to commit, working tree clean
可以看到:沒有東西需要提交,工作目錄是干凈的。
3.1、版本回退
現在我們想看一下提交日志,用git log
查看:
$ git log
commit c73247bfb445ea48eb3cc634e9fa3cf38da3c363 (HEAD -> master)
Author: liuhuan <18512104146@163.com>
Date: Wed Dec 20 23:09:31 2017 +0800
add cool
commit 36cd3093230a020ee381bb59e7596096868e1ab7
Author: liuhuan <18512104146@163.com>
Date: Tue Dec 19 23:05:53 2017 +0800
a new file
這樣,很清楚的看到了從最近開始的所以提交記錄。
- commit 后面的一大串數字,就是我們提交的commit ID即我們提交的版本號,是十六進制來表示的。
現在我們想退回上個版本怎么辦呢?
在git中有一個指針
HEAD
指向當前版本,我們退回的時候只需要修改HEAD
指向某個版本就可以了:上個版本就是HEAD^
,上兩個版本就是HEAD^^
,100個版本就是HEAD~100
;當然也可以git reset --haed
+commit ID來退回某個版本,輸入ID的時候只需要輸入前幾位就可以了,沒必要全部輸入
值得一提的是:回到指定ID的時候是不用加HEAD的
現在輸入git reset --hard HEAD^
來退回上個版本:
$ git reset --hard HEAD^
HEAD is now at 36cd309 a new file
可以看到,我們已經回到了第一次提交新文件的版本,可以回去看下txt:
git is a version control system
magicliu is a handsome man
果然,cool不在了。
我們再用git log
看一下日志:
$ git log
commit 36cd3093230a020ee381bb59e7596096868e1ab7 (HEAD -> master)
Author: liuhuan <18512104146@163.com>
Date: Tue Dec 19 23:05:53 2017 +0800
a new file
可以看到add cool這個日志也不存在了。
現在,我們發現退回版本錯誤了。想回到之前的版本怎么做呢?
只需要去網上翻到之前的日志,找到那個commit ID。然后git reset --hard
+commit ID退回那個版本就行了:
$ git reset --hard c73247bfb445
HEAD is now at c73247b add cool
可以看到,已經回到了cool那個版本,可以看下txt文件:
git is a version control system
magicliu is a handsome cool man
cool~又回來了!
3.2、版本回退
比如,我們修改了一些東西。發現是沒有$ 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: liu.txt
no changes added to commit (use "git add" and/or "git commit -a")
可以看到代碼提交:modified liu.txt即這個文件被修改;git add file去提交到緩存區;git checkout -- file去discard丟棄,放棄工作區的修改。
值得一提的是哪怕你提交修改到了緩存區,但沒有提交到版本庫代碼依然是可以的。
3.3、刪除文件
我們在文件夾中新建一個test.txt文件,然后git add-->git commit提交到版本庫。
我們刪除文件時,可以直接在文件夾中刪除,或者在git 中用 rm file
指令刪除(rm 就可以啦~不用加git);
現在,工作區是刪除了。可以版本庫里依然存在啊,git status
查看一下狀態:
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
可以看到我們刪除了test.txt文件。現在有兩種選擇:
一、版本庫中也刪除這個文件:git rm file
刪除掉,并且git commit -m ''
提交修改:
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d17efd8] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
二、刪錯了,需要恢復回來:
$ git checkout -- test.txt
git chekcout
其實是用版本庫里的版本替換工作區的版本,無論工作區是修改還是刪除,都可以“一鍵還原”。
4、遠程倉庫
git遠程倉庫為git的殺手級功能之一。Git是分布式版本控制系統,同一個Git倉庫,可以分布到不同的機器上。而且是沒有主次之分的。而GitHub這個網站就是提供git倉庫托管服務的。
注:hub就是樞紐的意思。
那么如何將本地電腦關聯到自己的github賬戶上呢?
首先,找到自己電腦上的SSH key位置:
然后在github上找到添加key并進行添加:
title任意填寫,key里面是
id_rsa.pub
文件內容。然后點擊提交就可以了,這樣就可以往自己的github上進行推送了。但是github上的項目是開源的,其他人都可以看見,但是不可以修改。當然也是可以花錢變成私有的。注:SSH 為 Secure Shell的縮寫,即安全外殼協議。
4.1添加遠程倉庫
現在我們在本地有了一個git倉庫,又想在github上有一個遠程倉庫。并讓這兩個倉庫遠程同步,這樣遠程倉庫既可以當做備份,也可以多人進行協作工作。那么該怎么做呢?
首先,在github上找到一個"new repository"填寫名字并新建倉庫:
新倉庫是這樣的:
![(G5WGTMF~%J350FD$1U12]N.png](http://upload-images.jianshu.io/upload_images/5704367-3ac60096be290c97.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
這時,GitHub告訴我們可以關聯一個本地倉庫將內容推送上去,也可以新建一個倉庫。這時按照提示在本地倉庫執行下面的命令,關聯遠程倉庫并推送:
git remote add origin git@github.com:beipinggao/2018-1-14.git
git push -u origin master
推送成功后就可以看到遠程倉庫和本地倉庫有一樣的文件:
![F]8D`5AY8M5GX4RLYS)BV9V.png](http://upload-images.jianshu.io/upload_images/5704367-f827c6d9359c19da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 由于遠程庫是空的,我們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在以后的推送或者拉取時就可以簡化命令。
現在開始,本地提交了之后就可以通過
git push origin master
把本地提交推送到github上。
總結:
1、關聯遠程倉庫:git remote add origin git@server-name:path/repo-name.git
2、第一次推送master分支內容時加 -u:git push -u origin maste
,u即upstream上游的意思。
3、之后本地向github遠程分支提交:git push origin master
4.2從遠程倉庫克隆
只需輸入下面指令就可以了:
git clone +git倉庫地址
5、分支管理
分支在實際中有什么用呢?假設你準備開發一個新功能,但是需要兩周才能完成,第一周你寫了50%的代碼,如果立刻提交,由于代碼還沒寫完,不完整的代碼庫會導致別人不能干活了。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風險。
現在有了分支,就不用怕了。你創建了一個屬于你自己的分支,別人看不到,還繼續在原來的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到開發完畢后,再一次性合并到原來的分支上,這樣,既安全,又不影響別人工作。
5.1創建與合并分支
創建并切換到該分支:
$ git checkout -b dev
Switched to a new branch 'dev'
b即branch分支的意思,就相當于執行了下面的兩行代碼:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
可以用git branch
查看所有分支
$ git branch
* dev
master
- 其中,*代表當前所在的分支。
我們在Dev分支上進行修改之后,需要合并到master分支上該怎么做呢?
1、先切回主分支
$ git checkout master
Switched to branch 'master'
2、將dev分支內容合并到master分支上
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
3、刪除dev分支
$ git branch -d dev
Deleted branch dev (was fec145a).
5.2解決沖突
假如在一個分支liu上進行修改提交,另一個分支master上也進行修改提交。
然后在主分支上進行分支和并git merge dev
的時候就會出現代碼沖突的問題:
$ git merge liu
Auto-merging liu.txt
CONFLICT (content): Merge conflict in liu.txt
Automatic merge failed; fix conflicts and then commit the result.
這時,文件時這樣的:
liuhuan
<<<<<<< HEAD
master
=======
dev
liu
>>>>>>> liu
可以看到沖突的代碼是用箭頭和等號來顯示出來,我們修改沖突代碼之后,需要重新git add
git commit
提交代碼之后才可以重新merge:
$ git merge liu
Already up to date.
可以看到已經merge成功。
5.3bug分支
我們需要解決bug的時候,可以新建一個bug分支。然后進行修改,之后合并到主分支再進行刪除就可以啦。
修改bug時,可以將開發分支gitstash
隱藏起來起來,之后再git stash pop
取消隱藏就可以了。
同樣,添加新功能時也可以先建分支這樣來處理。
5.4多人合作開發
有6點總結:
- 查看遠程庫信息,使用
git remote -v
; - 本地新建的分支如果不推送到遠程,對其他人就是不可見的;
- 從本地推送分支,使用
git push origin branch-name
,如果推送失敗,先用git pull
抓取遠程的新提交; - 在本地創建和遠程分支對應的分支,使用
git checkout -b branch-name origin/branch-name
,本地和遠程分支的名稱最好一致; - 建立本地分支和遠程分支的關聯,使用
git branch --set-upstream branch-name origin/branch-name
;
注:本地新建的分支如果沒有關聯遠程分支推送到遠程分支之后,在pull代碼時就會報如下錯誤:
You asked me to pull without telling me which branch you
want to merge with, and 'branch.production.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.
If you often merge with the same branch, you may want to
use something like the following in your configuration file:
[branch "debug"]
remote = <nickname>
merge = <remote-ref>
[remote "<nickname>"]
url = <url>
fetch = <refspec>
See git-config(1) for details.
這個時候就需要關聯一下遠程分支
- 從遠程抓取分支,使用
git pull
,如果有沖突,要先處理沖突。
6、標簽管理
發布一個版本時,我們通常先在版本庫中打一個標簽(tag),這樣,就唯一確定了打標簽時刻的版本。將來無論什么時候,取某個標簽的版本,就是把那個打標簽的時刻的歷史版本取出來。所以,標簽也是版本庫的一個快照。
Git的標簽雖然是版本庫的快照,但其實它就是指向某個commit的指針(跟分支很像對不對?但是分支可以移動,標簽不能移動),所以,創建和刪除標簽都是瞬間完成的。
Git有commit,為什么還要引入tag?
“請把上周一的那個版本打包發布,commit號是6a5819e...”
“一串亂七八糟的數字不好找!”
如果換一個辦法:
“請把上周一的那個版本打包發布,版本號是v1.2”
“好的,按照tag v1.2查找commit就行!”
所以,tag就是一個讓人容易記住的有意義的名字,它跟某個commit綁在一起。
1、標簽管理常用命令:
- 命令
git tag <name>
用于新建一個標簽,默認為HEAD即當前版本,也可以指定一個commit id; -
git tag -a <tagname> -m "blablabla..."
可以指定標簽信息,標簽信息可以采用PGP(一個加密協議)簽名標簽; - 命令
git tag
可以查看所有標簽。是按字母排列的,不是按時間排列。
2、如何操作標簽
命令
git push origin <tagname>
可以推送一個本地標簽;命令
git push origin --tags
可以推送全部未推送過的本地標簽;命令
git tag -d <tagname>
可以刪除一個本地標簽;命令
git push origin :refs/tags/<tagname>
可以刪除一個遠程標簽。
6、關于GitHub的fork
fork:叉,分支的意思。就是將開源項目克隆到自己的GitHub遠程倉庫下。
三點總結:
1、在GitHub上,可以任意Fork開源倉庫;
2、自己擁有Fork后的倉庫的讀寫權限;
3、可以推送pull request給官方倉庫來貢獻代碼。GitHub上有這個按鈕,提供建議的。
具體的看這個解釋很直接:https://www.zhihu.com/question/21682976
好了,就總結到這里吧,有什么問題了一會再來補充~