配置全局的用戶名(--global此電腦全部git倉庫都會使用該配置)
$ git config --global user.name "Your Name"
配置全局的郵箱地址(--global此電腦全部git倉庫都會使用該配置)
$ git config --global user.email "email@example.com"
查看配置信息
$ git config --system --list ## 查看系統配置 $ git config --global --list ## 查看當前用戶配置 $ git config --local --list ## 查看當前倉庫配置
建立一個空目錄做爲版本庫目錄
$ mkdir learngit # 建立目錄learngit(即爲版本庫) $ cd learngit # 進入該目錄 $ pwd # 查看路徑 /Users/michael/learngit
初始化該目錄,使其能夠被git管理,此後該目錄會出現一個.git目錄(若是沒有可能被隱藏了,能夠用:ls -ah查看)
$ git init # 初始化該目錄以後會出現如下提示 Initialized empty Git repository in /Users/michael/learngit/.git/ $ ls -ah # 查看當前目錄文件,包括隱藏文件
在目錄下面新建一個文件,用於作測試,內容隨便
$ ls readme.php $ cat readme.php Git is a version control system. Git is free software.
將文件放入到倉庫只須要兩步
1). 告訴Git將要將要添加該文件到倉庫(add後面能夠跟多個文件用空格隔開,也能夠跟目錄,而且能夠將文件屢次分別add,只要在commit以前都算一次提交)php
$ git add readme.txt
2). 將文件提交到倉庫git
$ git commit -m "wrote a readme file" [master (root-commit) 74256b9] wrote a readme file 2 files changed, 6 insertions(+) create mode 100644 reademe.php create mode 100644 readme.php
==注意:每次修改,若是不用git add到暫存區,那就不會加入到commit中==
對文件進行修改,添加一個單詞,而後經過命令查看狀態
$ 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: readme.txt no changes added to commit (use "git add" and/or "git commit -a")
告訴咱們文件被修改過了,可是尚未準備提交的修改github
查看具體修改了哪些內容
$ git diff readme.php # 會顯示出修改的內容信息
查看全部的版本日誌
$ git log # 若是須要精簡到一行的信息加上參數 --pretty=oneline 便可
在Git中,用HEAD表示當前版本,也就是最新的提交1094adb... (注意個人提交ID和你的確定不同), 上一個版本就是HEAD^, 上上一個版本就是HEAD^^, 固然往上100個版本寫100個^比較容易數不過來,因此寫成HEAD~100
以下,回退到上一個版本,執行命令後用cat查看發現內容已經變了
$ git reset --hard HEAD^
若是我回到過去的版本了,隨後又想恢復到原來的版本怎麼辦,只要命令框沒有關閉,還能夠找到原來的版本號,取前幾位就能夠,可是也不能太少,用如下命令
$ git reset --hard 3642b # 版本號寫前幾位就能夠,可是也不能過短,能識別就行
可是若是手賤關閉了命令框,關閉了電腦,怎麼辦,回退版本後發現錯了,還想回來怎麼辦
$ git reflog # 這個命令能夠查看你全部操做命令的日誌,固然裏面是有版本號的了
工做區概念:就是你在本地電腦裏能看到的目錄數據庫
版本庫概念:工做區有一個隱藏目錄.git,這個不算工做區,而是Git的版本庫。安全
前面講了咱們把文件往Git版本庫裏添加的時候,是分兩步執行的:服務器
第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;第二步是用git commit提交更改,實際上就是把暫存區的全部內容提交到當前分支。app
由於咱們建立Git版本庫時,Git自動爲咱們建立了惟一一個master分支,因此,如今,git commit就是往master分支上提交更改。ssh
狀況一:準備提交以前若是發現了錯誤(==add以前==)測試
- 一種是readme.txt自修改後尚未被放到暫存區,如今,撤銷修改就回到和版本庫如出一轍的狀態;
- 一種是readme.txt已經添加到暫存區後,又做了修改,如今,撤銷修改就回到添加到暫存區後的狀態。
- 總之,就是讓這個文件回到最近一次git commit或git add時的狀態。
$ git checkout -- readme.php
狀況二:已經提交到暫存區了(==add以後commit以前==)
1). git reset命令既能夠回退版本,也能夠把暫存區的修改回退到工做區。當咱們用HEAD時,表示最新的版本。
$ git reset HEAD readme.php
2). 此時就變爲了狀況一,暫存區沒有了,可是工做區還有
$ git checkout -- readme.php
狀況三:已經提交到了分支(==commit以後==)fetch
能夠採用版本回退的方法狀況四:不只提交到了分支,還推送到了遠程版本庫
那麼恭喜你,本次撤銷修改是不可能的了
當你從本地刪除了一個文件,能夠有兩種選擇:
1). 肯定要刪除了,而後將分支中的文件也刪除掉
$ git rm test.php $ git commit -m "remove test.php"
2). 發現刪錯了,想要將其從分支恢復回來
$ git checkout -- test.php
添加遠程倉庫
[1]. 第一步:==建立SSH Key==。在用戶主目錄下,看看有沒有.ssh目錄,若是有,再看看這個目錄下有沒有id_rsa和id_rsa.pub這兩個文件,若是已經有了,可直接跳到下一步。若是沒有,打開Shell(Windows下打開Git Bash),建立SSH Key:
$ ssh-keygen -t rsa -C "youremail@example.com"
注意:須要把郵件地址換成你本身的郵件地址,而後一路回車,使用默認值便可,密碼不必設置,若是一切順利的話,能夠在用戶主目錄裏找到.ssh目錄,裏面有id_rsa和id_rsa.pub兩個文件,這兩個就是SSH Key的祕鑰對, ==id_rsa是私鑰==,不能泄露出去,==id_rsa.pub是公鑰==,能夠放心地告訴任何人[2]. 第二步:登錄GitHub,打開「Account settings」,「SSH Keys」頁面:
而後,點「==Add SSH Key==」,填上任意Title,在Key文本框裏粘貼id_rsa.pub文件的內容
==爲何GitHub須要SSH Key呢?==
由於GitHub須要識別出你推送的提交確實是你推送的,而不是別人冒充的,而Git支持SSH協議,因此,GitHub只要知道了你的公鑰,就能夠確認只有你本身才能推送。固然,GitHub容許你添加多個Key。假定你有若干電腦,你一下子在公司提交,一下子在家裏提交,只要把每臺電腦的Key都添加到GitHub,就能夠在每臺電腦上往GitHub推送了。
最後友情提示,在GitHub上免費託管的Git倉庫,任何人均可以看到喔(但只有你本身才能改)。因此,不要把敏感信息放進去。
[3]. ==在github上新建空的版本庫==
$ git remote add origin git@github.com:KeepFang/learngit.git
注意:要將KeepFang換成本身的github用戶名,learngit換成本身的遠程庫名字添加後,遠程庫的名字就是origin,這是Git默認的叫法,也能夠改爲別的,可是origin這個名字一看就知道是遠程庫。
[4]. 將本地內容推送到遠程庫
$ git push -u origin master # 將本地庫內容推送到遠程庫
把本地庫的內容推送到遠程,用git push命令,其實是把當前分支master推送到遠程。因爲遠程庫是空的,咱們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送到遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在之後的推送或者拉取時就能夠簡化命令。
從如今起,只要本地做了提交,就能夠經過命令:
$ git push origin master
當你第一次使用Git的clone或者push命令鏈接GitHub時,會獲得一個警告
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established. RSA key fingerprint is xx.xx.xx.xx.xx. Are you sure you want to continue connecting (yes/no)?
這是由於Git使用SSH鏈接,而SSH鏈接在第一次驗證GitHub服務器的Key時,須要你確認GitHub的Key的指紋信息是否真的來自GitHub的服務器,輸入yes回車便可。Git會輸出一個警告,告訴你已經把GitHub的Key添加到本機的一個信任列表裏了:
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
git clone git@github.com:用戶名/版本庫名.git
你也許還注意到,GitHub給出的地址不止一個,還能夠用 https://github.com/michaellia...。實際上,Git支持多種協議,默認的git://使用ssh,但也可使用https等其餘協議。使用https除了速度慢之外,還有個最大的麻煩是每次推送都必須輸入口令,可是在某些只開放http端口的公司內部就沒法使用ssh協議而只能用https。
分支在實際中怎麼用呢?團隊合做開發一個項目,你建立了一個屬於你本身的分支,別人看不到,還繼續在原來的分支上正常工做,而你在本身的分支上幹活,想提交就提交,直到開發完畢後,再一次性合併到原來的分支上,這樣,既安全,又不影響別人工做。
1). 建立分支
$ git checkout -b dev # 建立分支dev並切換到該分支
等價於
$ git branch dev # 建立分支 $ git checkout dev # 切換分支
$ git branch # 列出全部分支,當前分支前面會標一個 * 號
2). 合併分支
$ git checkout master # 切換到主分支 $ git merge dev # 將dev分支與當前分支合併 $ git branch -d dev # 合併完成以後就能夠刪除dev分支了 $ git branch # 刪除以後再次查看分支,發現只剩下master分支了
一般,合併分支時,若是可能,Git會用Fast forward模式,但這種模式下,刪除分支後,會丟掉分支信息。若是要強制禁用Fast forward模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就能夠看出分支信息。
$ git merge --no-ff -m "merge with no-ff" dev # 禁用fast forward快速合併模式, ## 合併分支時,加上--no-ff參數就能夠用普通模式合併, ## 合併後的歷史有分支,能看出來曾經作過合併, ## 而fast forward合併就看不出來曾經作過合併。 $ git log --graph --pretty=oneline --abbrev-commit # 而後再查看分支歷史
3). 解決衝突
當Git沒法自動合併分支時,就必須首先解決衝突。解決衝突後,再提交,合併完成。解決衝突就是把Git合併失敗的文件手動編輯爲咱們但願的內容,再提交。
合併以後,刪除沒用的分支
$ git log --graph --pretty=oneline --abbrev-commit # graph參數是查看分支合併圖
在實際開發中,咱們應該按照幾個基本原則進行分支管理:
首先,master分支應該是很是穩定的,也就是僅用來發布新版本,平時不能在上面幹活;
那在哪幹活呢?幹活都在dev分支上,也就是說,dev分支是不穩定的,到某個時候,好比1.0版本發佈時,再把dev分支合併到master上,在master分支發佈1.0版本;
你和你的小夥伴們每一個人都在dev分支上幹活,每一個人都有本身的分支,時不時地往dev分支上合併就能夠了。
當你正在開發一個新功能的時候,忽然有人反饋原先的項目存在一個bug,很天然想到新建一個分支來進行修復而後合併,可是如今你的工做還沒完成,又不能提交,這時候就須要用到 ==保存現場== 功能
$ git stash # 將當前工做的現場儲存起來 $ git status # 這時候再看發現工做區是乾淨的能夠放心建立分支
1). 肯定在哪一個分支修復bug,就從哪一個分支建立臨時分支,假設是master
$ git checkout master # 切換到master分支 $ git checkout -b issue-101 # 建立並切換到bug分支 $ git add readme.txt $ git commit -m "fix bug 101" # 模擬修復bug $ git checkout master # 切換到主分支 $ $ git merge --no-ff -m "merged bug fix 101" issue-101 # 將bug分支與主分支合併
2). 修復bug後繼續dev分支開發
$ git checkout dev # 繼續返回dev寫未完成的工做 $ git status # 此時工做區是乾淨的,那以前保存的現場在哪裏呢 $ git stash list # 查看保存的工做現場
3).恢復以前的現場
$ git stash pop # 恢復現場並刪除該stash $ git stash list # 再次查看發現,已經沒有stash了
等價於
$ git stash apply # 恢復現場 $ git stash drop # 刪除stash $ git stash list # 再次查看發現,已經沒有stash了
還能夠屢次stash,恢復指定現場
$ git stash apply stash@{0} # 恢復指定編號的現場
開發一個新功能,最好新建一個分支,至於怎麼新建分支這個上面已經有概述
特殊狀況:若是須要丟棄一個未合併的分支
$ git branch -D feature-vulcan # 若是要強制丟棄一個未合併的分支須要用大寫的D參數
1). 查看遠程倉庫信息
$ git remote # 查看遠程倉庫信息
$ git remote -v # 查看遠程倉庫詳細信息
2). 推送分支到遠程庫
$ git push origin dev # 推送當前分支到指定的遠程分支
可是,==並非必定要把本地分支往遠程推送==,那麼,哪些分支須要推送,哪些不須要呢?
master分支是主分支,所以要時刻與遠程同步;
dev分支是開發分支,團隊全部成員都須要在上面工做,因此也須要與遠程同步;
bug分支只用於在本地修復bug,就不必推到遠程了,除非老闆要看看你每週到底修復了幾個bug;
feature分支是否推到遠程,取決於你是否和你的小夥伴合做在上面開發。
總之,就是在Git中,分支徹底能夠在本地本身藏着玩,是否推送,視你的心情而定!
3). 抓取分支
3.1. 模擬一個你的小夥伴,能夠在另外一臺電腦(注意要把SSH Key添加到GitHub)或者同一臺電腦的另外一個目錄下克隆:
$ git clone git@github.com:用戶名/倉庫名.git # 從服務器上拉取項目到本地 $ git branch # 拉取下來以後本地默認只能看到一個master分支
3.2. 如今你的小夥伴要在dev分支上面進行開發了,因而他須要建立dev分支在本地
$ git checkout -b dev origin/dev # 建立=(遠程)=的dev分支到本地
3.3. 如今就能夠開發dev分支,並時不時提交到遠程
$ git add env.txt # 模擬開發dev分支 $ git commit -m "add env" $ git push origin dev # 提交分支到遠程
3.4. 若是多我的都在開發dev分支呢,爲了保證一致性,須要先更新再提交
$ git add env.txt # 模擬你的提交 $ git commit -m "add new env" $ git push origin dev # 假設你的隊友已經修改過dev分支了,那麼會推送失敗 $ git pull # 須要先pull更新代碼爲最新,可能還會報錯, ## 由於沒有創建本地dev與遠程dev分支的直接連接 $ git branch --set-upstream-to=origin/dev dev # 按照報錯信息創建連接 $ git pull # 這時候返回pull成功,可是可能你和隊友修改了一樣地方會提示有衝突 $ git commit -m "fix env conflict" # 解決衝突後,先提交,而後push $ git push origin dev# 修復衝突後再次推送
多人協做,分支很混亂,若是有強迫症非要整理成一條線呢
1). 原來分支圖是這樣
$ git log --graph --pretty=oneline --abbrev-commit # 查看分支線 * 582d922 (HEAD -> master) add author * 8875536 add comment * d1be385 (origin/master) init hello * e5e69f1 Merge branch 'dev' |\ | * 57c53ab (origin/dev, dev) fix env conflict | |\ | | * 7a5e5dd add env | * | 7bd91f1 add new env ...
注意到Git用(HEAD -> master)和(origin/master)標識出當前分支的HEAD和遠程origin的位置分別是582d922 add author和d1be385 init hello,本地分支比遠程分支快兩個提交。2). 當咱們再次提交,很不幸,有我的已經提早提交了,出現了衝突,按照習慣先pull一下
$ git push origin master # 假設失敗了 $ git pull # 先pull一下 $ git status # 查看狀態 $ git log --graph --pretty=oneline --abbrev-commit # 再次查看分支線,發現分叉了, ## 可是如今繼續提交時徹底沒有問題的,就是線很差看 $ git rebase # 用命令美化線爲一條 $ git log --graph --pretty=oneline --abbrev-commit # 再次查看分支線,發現變爲了一條直線 $ git push origin master # 最後提交分支到遠程
==rebase的目的是使得咱們在查看歷史提交的變化時更容易,由於分叉的提交須要三方對比==。
tag就是一個讓人容易記住的有意義的名字,它跟某個commit綁在一塊兒。例如:v1.21). 建立標籤
$ git branch # 查看分支 $ git checkout master # 切換到分支 $ git tag v1.0 # 打標籤 $ git tag # 查看全部標籤
若是前面的忘記打標籤如今要補上怎麼辦
$ git log --pretty=oneline --abbrev-commit # 找到對應版本號 $ git tag v0.9 f52c633 # 指定版本號打標籤 $ git tag # 查看標籤
標籤不是按時間順序列出,而是按字母排序的。能夠用git show <tagname>查看標籤信息
$ git show v0.9 # 查看標籤信息 $ git tag -a v0.1 -m "version 0.1 released" 1094adb # 要想帶上標籤說明,能夠用-m參數 $ git show v0.1 # 這個命令一樣能夠查看到標籤的說明信息
2). 操做標籤
刪除本地標籤
$ git tag -d v0.1
推送某個標籤到遠程
$ git push origin v1.0
一次性推送所有還沒有推送到遠程的本地標籤
$ git push origin --tags
刪除遠程標籤
$ git tag -d v0.9 # 先從本地刪除 $ git push origin :refs/tags/v0.9 # 刪除遠程標籤
在GitHub上,能夠任意Fork開源倉庫;本身擁有Fork後的倉庫的讀寫權限;
能夠推送pull request給官方倉庫來貢獻代碼。
1). 先註冊帳號後配置公鑰
2). 若是已經有了一個本地倉庫,想要關聯到碼雲
[1]. 首先在碼雲上面建立這個項目
[2]. 將本地庫只與碼雲庫關聯
$ git remote add origin git@gitee.com:用戶名/項目名.git
此時先查看遠程庫信息
$ git remote -v
而後刪除遠程庫信息,關聯到gitee
$ git remote rm origin # 刪除遠程庫 $ git remote add origin git@gitee.com:用戶名/項目名.git # 關聯碼雲庫 $ git remote -v # 再次查看遠程庫信息
[3]. 同時關聯github和碼雲
使用多個遠程庫時,咱們要注意,git給遠程庫起的默認名稱是origin,若是有多個遠程庫,咱們須要用不一樣的名稱來標識不一樣的遠程庫。1). 先刪除已關聯的名爲origin的遠程庫
$ git remote rm origin
2). 添加Github連接
$ git remote add github git@github.com:用戶名/倉庫名.git # 注意遠程庫叫github不叫origin了
3). 添加碼雲連接
git remote add gitee git@gitee.com:用戶名/倉庫名.git # 注意遠程庫叫gitee不叫origin了
$ git remote -v # 此時發現關聯了github和gitee等多個遠程庫
[4]. 而後就能夠正常的pull和push了
## 更新代碼爲最新 git pull gitee master git pull github master ## 推送到github遠程庫 $ git push github master ## 推送到gitee遠程庫 $ git push gitee master ## 若是不行就用 git push -u gitee master
有些文件必須在項目目錄,可是又不能提交他們,好比數據庫密碼配置文件
解決方法:在Git工做區的根目錄下建立一個特殊的.gitignore文件,而後把要忽略的文件名填進去,Git就會自動忽略這些文件,詳情參考廖雪峯git。
忽略文件的原則是:
- 忽略操做系統自動生成的文件,好比縮略圖等;
- 忽略編譯生成的中間文件、可執行文件等,也就是若是一個文件是經過另外一個文件自動生成的,那自動生成的文件就不必放進版本庫,好比Java編譯產生的.class文件;
- 忽略你本身的帶有敏感信息的配置文件,好比存放口令的配置文件。
有些時候,你想添加一個文件到Git,但發現添加不了,緣由是這個文件被.gitignore忽略了
這個時候能夠採用兩種方法
1). 一種是-f直接強制提交
$ git add -f App.class
2). 一種是檢查是否是過濾用的配置文件寫錯了
$ git check-ignore -v App.class
配製方法:
$ git config --global alias.st status # 執行以後,就能夠用st代替status $ git config --global alias.unstage 'reset HEAD' # 用unstage代替reset HEAD
配置文件:配置好的規則實際上保存在本地的文件裏面
配置Git的時候,加上--global是針對當前用戶起做用的,若是不加,那隻針對當前的倉庫起做用。每一個倉庫的Git配置文件都放在.git/config文件中,[alias]下面就是別名,可直接添加、修改或刪除
[core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [remote "origin"] url = git@github.com:michaelliao/learngit.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master [alias] last = log -1