git基礎

git基礎

git是什麼

git是一個分佈式版本控制系統,我們熟悉的svn是一個集中式的版本控制系統。分佈式意味着每一臺運行git的電腦既可以是客戶端,也是“服務器”,客戶端存儲的數據與服務器存儲的數據沒有什麼差別(同步後)。git與svn使用方法比較類似,但差別很大。其中一個比較大的差別是:svn等集中式版本控制系統一般是基於某個版本存儲變化的數據,而git是存儲各個時間點的完整鏡像,如果某個文件沒有變化,則只存儲一個鏈接。分佈式的一個明顯的好處是,如果服務器崩潰了,我們可以從任意一臺clone過它的客戶端電腦進行恢復(可能會丟失一些服務端的hooks,但所有的版本控制數據都在)。

初始化一個倉庫

$ git init
$ git add *.c
$ git commit -m 'initial project version'

git init會在當前目錄創建一個.git子目錄,用於存放版本控制信息。此時還沒有對任何文件進行版本控制。
git add .c會把當前目錄下的所有.c文件添加到提交列表,稱之爲stage files
開發過程中,我們更多的是clone一個倉庫。

克隆一個倉庫

$git clone https://github.com/libgit2/libgit2
$ git clone https://github.com/libgit2/libgit2 mylibgit2

類似於svn 的check out,git clone會克隆服務器當前時間點的所有數據。
想要clone到指定目錄,可以在後面添加(上面例子中的第二條命令)。

檢查文件狀態

$ git status

可以查看新增了哪些文件?哪些文件變更了?哪些文件被刪除了?
這裏寫圖片描述
如上圖所示:README是更改過的文件,deletedFile.txt是被刪除的文件,newFile.txt是新增的文件。
git status的輸出看起來比較繁雜,有沒有簡化的方式?答案是‘有’, 加-s參數:

$ git status -s

這裏寫圖片描述
沒有stage的文件notAdd.txt被標識爲”??”。新增文件有一個’A’,更新的文件被標識爲’M’。上面輸出的每一行的前面部分其實有兩個列,第一列指明文件被staged,第二列指明文件被更新了。例如在下面的輸出中:README文件被更新了並且被staged了,然後又被更新了。deletedFile.txt被刪除並且被staged了。
這裏寫圖片描述

stage文件(加入提交列表)

只有stage的文件纔會進入提交列表,用git add 命令stage要提交的文件,變更的文件、新增的文件在提交之前都需要使用git add添加到提交列表,否則不會提交

$ git add README
$ git add newFile.txt

執行上面兩個命令之後,我們會看到更改的文件和新增的文件都被staged了(README和newFile.txt),下次執行git commit時,這兩個文件將會被提交到git倉庫。
這裏寫圖片描述
刪除的文件仍然處於unstaged狀態,既沒有進入提交列表。對於該文件的處理,命令行已經有提示,既:
git rm 刪除該文件
git checkout 放棄變更(恢復該文件)

刪除一個文件

$ git rm <file>

需要通過git rm 來顯示通知git移除一個文件

stage所有的變更文件

我們可以使用一個命令stage所有的變更文件

$ git add --all

這樣就不用當獨對每個刪除的、變更的、新增的文件單獨執行git add命令

恢復文件(放棄變更)

$ git checkout <file>

只有處於unstaged狀態的文件才能夠被恢復。

unstage文件(從提交列表刪除)

$ git reset HEAD <file>

不想提交某個文件時,可以使用這個命令。

文件狀態生命週期

這裏寫圖片描述
文件會有4種狀態: Untracked, Unmodified, Modified, Staged。
新增文件處於Untracked狀態,使用git add 命令添加文件後,文件狀態轉換爲Staged狀態。
Clone後或提交後(還未做任何文件更改),所有文件處於Unmodified狀態。對文件進行編輯後,文件狀態轉換爲Modified狀態。
只有處於Staged的文件纔會被提交。

過濾規則(設置忽略哪些文件)

通常,像.o,.tmp, *~這類文件,它們通常都是一些臨時文件、編譯生成的文件、日誌文件等,我們希望git不要自動添加,甚至不要顯示它們的untracked狀態。我們可以創建.gitignore文件類設置過濾規則。
下面是一個簡單的.gitignore文件例子:

$ cat .gitignore
*.[oa]
*~
*tmp

第一行告訴git忽略任何以”.a”和”.o”結尾的文件;第二行告訴git忽略任何以波浪符(~)結尾的文件;第三行告訴git忽略任何以”tmp”結尾的文件;
.gitignore編寫規則如下:

  • 空行或以#開頭的行被忽略
  • 支持標準的shell樣式正則表達式
  • 以斜槓”/”結尾可以忽略目錄
  • 以”!”開頭可以對模式取反

GitHub爲多個項目維護着一個相當全面的.gitignore文件列表,可以進行參考。

文件內容的具體變更

$ git diff
$ git diff --staged

第一個命令顯示沒有被staged的內容,第二個命令顯示已經被staged的內容。

提交變更

要記住:任何仍然處於unstaged狀態的東西 –– 任何你創建或更改了,但在你編輯之後沒有對其執行git add的文件都不會被commit。

$ git commit -m "log message is here"
$ git commit -a -m "log message is here"

-a參數告訴git自動stage變更文件(更新的,刪除的,但不包括新增文件),使你可以跳過git add部分。
不加-m會彈出一個文本編輯器,要求你編輯commit message。具體彈出什麼編輯器跟你的配置有關。可用通過shell $EDITOR環境變量來指定用哪個編輯器,還可以通過git config –global core.editor進行設置。下面的例子設置gedit爲默認編輯器:

$ declare -x EDITOR='gedit'
$ git git config --global  core.editor gedit

移動文件

$ git mv oldfile newfile

相當於如下命令:

$ mv oldfile newfile
$ git rm oldfile
$ git add newfile

查看提交歷史

可直接使用

$ git log

不過現實的信息比較簡略。下面是一些常用的參數:
-p 顯示每個commit引入的差異。
–stat 顯示每個commit的簡略統計信息
另一個很有用的選項是–pretty,它可以改變log輸出格式。當你想要產生日誌用於機器分析時,這種方式很有用。例如:

$ git log --pretty=format:"%h - %an, %ar : %s"
9a471ae - uvsjoh, 7 hours ago : third commit
ac1e996 - uvsjoh, 8 hours ago : first commit

下面是一些常用的format選項:
%H Commit hash
%h Abbreviated commit hash
%T Tree hash
%t Abbreviated tree hash
%P Parent hashes
%p Abbreviated parent hashes
%an Author name
%ae Author e-mail
%ad Author date (format respects the –date=option)
%ar Author date, relative
%cn Committer name
%ce Committer email
%cd Committer date
%cr Committer date, relative
%s Subject

撤銷操作

有的時候,你可能忘記添加文件,或想要完善commit message,想要再次提交。如果能再上次提交的基礎上提交就再好不過了。使用下面的命令可以做到。

$ git commit --amend

這將會覆蓋上一次的提交,即兩次提交變成了一次。

切換開發分支

一個代碼倉庫裏面可能會有多個分支,有一個是當前工作分支,提交時是默認提交到當前開發分支的。git branch可查看有哪些分支,其中標星號”*”的是當前工作分支。

$ git branch -v
  master  059a5c3 second commit
* testing 1afa3c0 third commit
git checkout <branch>可以切換分支
$ git checkout master
Switched to branch 'master'
master分支
Icon

每個Git倉庫都會有一個master分支,它並不是一個特殊的分支,其實它就和其它分支一樣。之所以每個倉庫都會有,是因爲git init命令默認創建了master分支,一般情況下很少有人會去改它。
分支模型是git的殺手鐗,更多細節可以參考:Git Branching - Branches in a Nutshell

遠程分支

查看遠程倉庫信息

$ git remote -v
origin  ssh://[email protected]:29418/u4/u4 (fetch)
origin  ssh://[email protected]:29418/u4/u4 (push)

查看遠程倉庫有哪些分支
$ git remote show origin
“origin”並不特殊
Icon
與master一樣,origin並沒有什麼特殊的含義,”origin”是你運行git clone時,默認給遠程倉庫的一個命名。

從服務器同步代碼

$ git fetch origin
$ git pull origin

git fetch不會自動merge到本地,origin自動merge到本地分支。git pull相當於git fetch 加上git merge。實際使用的過程中,使用git fetch會比較安全,可以先查看更新情況,再決定是否合併。

同步代碼到服務器

命令:git push (remote) (branch)

$ git push origin u4playground/dev_webview_cache_m3_final

實際上git自動把分支名feature/dev_webview_cache擴展爲refs/heads/feature/dev_webview_cache:refs/heads/feature/dev_webview_cache,意思是用我的本地feature/dev_webview_cache分支更新遠程feature/dev_webview_cache分支。

查看遠程分支

$ git branch -av
$ git branch -av | grep clear

刪除本地分支

$ git branch -d feature/dev_clear_record
$ git branch -D feature/dev_clear_record

刪除遠程

$ git push origin --delete feature/dev_crash_restore
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章