正好最近在逛GitHub的時候看到了一個學習git的項目,點進去一看,寓教于樂,闖關(guān)類型+互動的類型十分的有趣,就用了差不多一天的時間給學完了,感覺收獲頗多,然而平時生活中似乎還是git pull, git push用的多,于是尋思著還是得記下來,免得過段時間就忘干凈了。整理一下也有助于自己記憶吧。
注:
[argu] 代表此參數(shù)可以省略
staged files 表示已經(jīng)加入git 跟蹤的文件但是還未提交到commit文件
working tree 表示當前系統(tǒng)中的文件,未被git處理
commit 已經(jīng)被commit的文件
HEAD 表示當前git所指向的commit,即“版本指針”
我們假設(shè)從零開始,假設(shè)一個日常生活的流程來使用吧
- 首先是初始化,這個命令會在當前目錄下初始化一個.git目錄,我們大致關(guān)注一下.git項目的結(jié)構(gòu)
git init
├── HEAD //存儲當前HEAD指針指向的commit,一般是master
├── branches
├── config //文本文件,可以手動配置一些參數(shù)(用戶名、郵箱,默認的遠端分支等等)
├── description
├── hooks
├── info
├── objects
└── refs
- 接著是增加遠端倉庫的地址
git remote add <remote name> <remote url>
git remote add origin https://www.github.com/userName/repositoryName.git
注意這個origin表示的是遠端倉庫的名字而非master,本地git可以指定多個remote,例如可以再增加一個mirror: git remote add mirror ...
增加后可以在.git/config文件里看到
[remote "origin"]
url = https://www.github.com/test/test.git
fetch = +refs/heads/*:refs/remotes/origin/*
[remote "mirror"]
url = https://www.github.com/test/test2.git
fetch = +refs/heads/*:refs/remotes/mirror/*
其中fetch那一行表示的是本地分支與遠端分支的對應關(guān)系,默認是同名對應,即遠端的origin/master對應本地的master
- 接著是增加一個commit
首先我們先增加兩個修改(Windows下不適用)
echo aaa > a.txt
echo bbb > b.txt
通過git add <pathName> 來增加本地的修改到工作樹里面,一旦新文件被加進去,就會被git跟蹤狀態(tài)(staged)
git add *.txt
接下來就可以git commit 了
git commit -m "Add a.txt and b.txt"
這里順帶介紹下git commit 幾個比較重要的可選參數(shù)
-m (--message) 增加commit的消息
-a (--all) 把所有修改和刪除的文件自動stage(這個命令可以用來省略git add ),對新增文件無效(因為新增文件還沒有被stage)
--amend 修改某次commit的信息,不會產(chǎn)生新的commit
--no-edit 表示不更改某次commit的信息(在修改commit的時候才會用到)
例如你提交了commit之后發(fā)現(xiàn)自己拼寫錯誤了,為了這個重新生成一個commit怕被同事笑話,那么就可以直接修改代碼,然后使用以下命令
git commit -a -amend --no-edit
那么一切就似乎從來沒有發(fā)生過
- 那么接下來似乎就應該把自己的修改push到遠端了,一個簡單的push命令可以解決問題(本文中作為初始化遠端倉庫的話可用),但是并非總是最佳的實踐,因為你不知道是否已經(jīng)有人更改過了遠端的倉庫,可以先使用
git fetch [<remote>] [<branch>]
- remote可省略,省略則默認為origin
- branch可省略,默認為與本地當前的branch名字一致
之后可以用git diff 命令查看兩次分支的差異
git diff HEAD origin/master
git diff [<path>] // 查看當前working tree與staged files文件的區(qū)別,注意只包含刪除與修改的,新增文件未被納入跟蹤
git diff --cached [<commit>] [<path>] //查看當前staged files與某次commit的文件的區(qū)別,commit可省略,默認為HEAD
git diff <commit> [path]//比較working tree files 和某次commit 文件的區(qū)別,commit不可省略,否則是第一種情況
git diff <commit> <commit> [<path>] //比較兩次文件的差異
接下來有兩個選擇
- git rebase 將本地的commit“偽裝”成在遠端的commit之后發(fā)生
- -- continue:遇到?jīng)_突時手動解決后繼續(xù)rebase
- -- skip 遇到?jīng)_突時跳過
- -- abort 遇到?jīng)_突時中止
- git merge 將本地的commit與遠端的commit merge之后形成一個新的merge commit??赡軙袥_突,此時需手動解決
git fetch + git merge = git pull
git fetch + git rebase = git pull -- rebase
git merge能保留所有原始記錄,而git rebase能使得項目的分支變得簡單易讀。
選擇哪一個并沒有定論,個人感覺是如果不是特別重要的兩邊都需要保留的commit(例如兩個人獨立開發(fā)很久,終于要合并了)的話,選擇rebase會是一個比較好的選擇。
- 現(xiàn)在可以進行g(shù)it push了
git push <remote> <branch>
先進行第四步保證git push可以成功。
- 全過程中我們都可以使用Git status來查看狀態(tài),它能給出一些提示的命令,且無任何實際效果,對于新手很有幫助,可以多敲這個命令。
git status
總結(jié)
到了這一步,日常使用Git的需求基本就得到滿足了,我們模擬了新建倉庫,pull 和push的操作,如何比較不同,解決沖突等等。
其實git文檔齊全,你可以使用git <command> --help 來獲取某個命令的詳細文檔,解釋的十分清楚。筆者建議要邊學邊實踐,能夠加深認識。
但是如果Git僅僅只有這樣的功能是不能夠成為最流行的版本管理工具的。Git最強大的功能在于其強大的分支管理。本文中粗略涉及了HEAD,master等分支的名字,merge,rebase等分支合并的行為,但是沒有細講。筆者有意在下一篇中繼續(xù)詳細講講git 分支的使用。
下一篇涉及的Git 命令
如何選擇“后悔藥”:
git revert
git reset分支管理
git checkout
git branch
git cherry-pick
git rebase -i其他git常見問題
.gitignore
大小寫問題
已經(jīng)被staged的文件加入gitignore后無效
git 配置問題(local, global)
重寫git的提交記錄
如果覺得本文對你有幫助的話,請點個喜歡。你的喜歡是對筆者最大的鞭策??
如果覺得有任何疑問,可以在評論區(qū)里提出。
下轉(zhuǎn)Git使用小結(jié)(二)