
You shall eat the fruit of the labor of your hands; you shall be blessed, and it shall be well with you.
在確定好了要學習使用git以及GitHub之后,我制定了如下的學習步驟:
- 學習< learn python the hard way > command line 教程
- 閱讀git官方文檔,觀看官方視頻介紹
- 學習廖雪峰的git教程,將教程里面的代碼逐行逐字在git bash中敲出來
以下筆記來源于廖雪峰的教程
Introduction
git - 版本控制工具 - version control
注意:版本控制,只針對文本文件(.txt)格式,圖片,視頻等二進制的不可以,word也是二進制,也不行
注意:windows下的記事本不能用,要用Notepad++
安裝git bash后,輸入如下兩行配置用戶名以及郵箱
git config --global user.name "your name"
git config --global user.email "your email"
注意:git config命令的--global參數(shù),用了這個參數(shù),表示你這臺機器上所有的Git倉庫都會使用這個配置,當然也可以對某個倉庫指定不同的用戶名和Email地址
創(chuàng)建版本庫
版本庫:Repository
選擇一個directory,創(chuàng)建一個空目錄作為git倉庫
eg:
mkdir learngit
cd learngit
git init:將這個文件夾變?yōu)間it倉庫
添加文件到git 倉庫
分兩步:
git add readme.txt
git commit -m"description"
-
git add可以多次添加不同的文件到暫存區(qū)(stage) -
git commit可以把所有暫存區(qū)內(nèi)的多個文件一次性全部提交
不同版本間的切換
cat readme.txt用來將文件內(nèi)容顯示出來
git status用來得知當前工作區(qū)(working directory)的狀態(tài)
git diff readme.txt查看修改的內(nèi)容
注意: git diff要用在git add readme.txt之前
git log:顯示從最近到最遠的(commit)命令歷史
如果嫌顯示的太多了
可以用git log --pretty=oneline就只會顯示一行commit id
版本回退
- 退回上一版本
git reset --hard HEAD^
- 退回上上本版
git reset --hard HEAD^^
- 退回100個版本之前
git reset --hard HEAD~100
HEAD相當于一個指針,指向當前版本
git reset --hard commit_id 在歷史版本之間穿梭
commit id使用前幾位即可
git log用來查看提交歷史
git reflog查看歷史版本信息

工作區(qū)與暫存區(qū)

所以
git add相當于:把文件修改添加到暫存區(qū)stage
git commit相當于:把暫存區(qū)內(nèi)所有的內(nèi)容提交到當前分支(master)
簡言之:需要提交的文件放在stage,然后用
commit一次性全部提交stage的所有修改
管理修改
git是用來管理修改,不是管理文件的
所以
如果不add到stage,就不會被commit到master分支
git diff HEAD -- readme.txt:查看commit后,working dict和版本庫里面最新的版本之間的區(qū)別

git diff是將working directory 與stage比較
git diff --cache是將stage與master分支比較
補充:vi命令(直接在bash里創(chuàng)建一個txt并寫入內(nèi)容)的使用
-
vi進入界面 -
i進入插入模式 - 寫入內(nèi)容
-
esc退出插入模式,進入命令模式 -
:w a.txt創(chuàng)建 a.txt并將寫入的內(nèi)容存放在a.txt內(nèi) -
:wq保存并離開vi -
q!強行退出vi
撤銷修改
1). git checkout -- readme.txt ( -- 很重要)
可以應對如下兩種情景
- 如果在working directory 修改了readme.txt,但是還沒有add到暫存區(qū),那么就撤銷至和版本庫一樣的狀態(tài)
- 如果在add到暫存區(qū)后修改了readme.txt,但是還沒有commit,那么就撤銷至剛剛add到暫存區(qū)的狀態(tài)
2).如果修改了readme.txt并且add到了暫存區(qū),那么用git reset HEAD readme.txt把暫存區(qū)里的重新放回到工作區(qū),然后再使用git checkout -- readme.txt
3).如果commit了,但是同時commit的還有很多其他文件,那么使用git reset HEAD^把readme.txt放回暫存區(qū),然后再提交或到工作區(qū)修改
刪除文件
commit了文件test.txt之后,如果在工作區(qū)刪除了test.txt
可以用git rm test.txt將版本庫里的也刪了
或者
git checkout test.txt撤銷刪除
遠程倉庫
github是一個為git提供遠程托管服務的服務器
通過SSH來加密
ssh-keygen -t rsa -C"your email"
然后一直回車
如果一切順利的話,可以在用戶主目錄里找到.ssh目錄,里面有id_rsa和id_rsa.pub兩個文件,這兩個就是SSH Key的秘鑰對,id_rsa是私鑰,不能公開,id_rsa.pub是公鑰,可以公開
然后在github里 找setting - SSH Keys 把id_rsa.pub的內(nèi)容黏貼進去。
GitHub允許你添加多個Key。假定你有若干電腦,你一會兒在公司提交,一會兒在家里提交,只要把每臺電腦的Key都添加到GitHub,就可以在每臺電腦上往GitHub推送了。
添加遠程倉庫
可以將本地的git倉庫和遠程github里的倉庫同步,將本地的文件推送到遠程
先在github里創(chuàng)建一個new repo 比如叫做learngit
注意:創(chuàng)建repository的時候不勾選Initialize this with a README ...
然后 在本地learngit 路徑下,運行如下命令 建立 本地 < ---- >遠程倉庫之間的聯(lián)系
輸入:git remote add origin git@server-name:path/repo-name.git
例如:git remote add origin git@github.com:fitzwong666/learngit.git
origin是git默認的遠程倉庫的叫法
將本地庫的內(nèi)容推送到遠程用
git push -u origin master命令,實際上是把當前分支master推送到遠程
由于遠程庫是空的,我們第一次推送master分支時,加上了-u參數(shù),Git不但會把本地的master分支內(nèi)容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關(guān)聯(lián)起來,在以后的推送時就可以直接用
git push origin master推送最新修改


從遠程倉庫克隆
要從遠程倉庫克隆,要先知道地址,然后用git clone進行克隆
eg:
git clone git@github.com/fitzwong666/gitskills.git
git支持https,但是通過ssh支持的原生git 協(xié)議最快
創(chuàng)建與合并分支
master是主分支,大家都不要在上面直接動工,最好分支到自己的branch工作
HEAD指向當前分支
創(chuàng)建new分支,并切換到new分支
git checkout -b new
這個命令相當于兩個命令合在一起,第一步git branch new,然后git checkout new
使用git branch可查看當前分支,在當前所在的分支前會顯示*
在new分支上做完修改后,add ->commit
然后用git checkout master切回master主分支
在當前分支上用git merge new將new分支合并到當前分支
然后git branch -d new刪除new分支
總結(jié)
- 查看分支:
git branch - 創(chuàng)建分支:
git branch <branch name> - 切換分支:
git checkout<branch name> - 創(chuàng)建 + 切換分支:
git checkout -b <branch name> - 合并某分支到當前分支:
git merge <branch name> - 刪除分支:
git branch d<branch name> - 刪除遠程分支:
git push origin : <branch name>(注意:branch name前的空格不能少)
解決沖突
在branch上改了并add commit
在master上改了并add commit
由于在這兩個節(jié)點上都改了文件
所以
這時
merge會產(chǎn)生conflict,需要手動解決沖突(通常是刪一個)后再add ——> commit
用git log --graph 可以看到分支合并圖
(git log --graph --pretty=oneline --abbrev-commit)顯示縮略圖
補1:
git log的各種變體:
補2:
有個文件夾A,在A中添加a.txt
用git add A/*可以把文件夾和里面的文件批量提交,不用一個一個上傳
補3:
- git add -A (stages All)
- git add . (stages new and modified, without deleted)
- git add -u (stages modified and deleted, without new)
分支管理策略
Master分支是用來發(fā)布新版本,平時不在上面干活,主要在A上,每個人都有自己的分支,然后在A上合并
Bug分支
用git stash彈到一個地方去處理bug
要在哪個分支(A)上修復bug,那么就在該分支上創(chuàng)建一個新分支來臨時修復Bug
git checkout -b issue-01
修復后add -> commit
然后切回A分支,
并合并git merge --no-ff m"description" issue-01
修復完成
然后用git stash list看看自己在哪里,
- 用
git stash pop刪除- 這一步也可以分為兩步
-
git stash apply先恢復 - 然后
git stash drop刪除
-
- 這一步也可以分為兩步
多人協(xié)作
查看遠程信息用 git remote -v
本地新建的分支如果不push到遠程,對他人不可見的
從本地推送分支的方法:git push origin branch-name
若推送失敗,是因為遠程分支比本地分支更新一點,先解決沖突(通常是刪一下)
要用git pull抓取遠程的提交,在本地合并
如果被git bash提示說「no tracking information」
- 若Pull失敗,是因為沒有設置本地分支a與遠程origin/a的鏈接;需要先建立本地分支和遠程分支的關(guān)聯(lián)
git branch --set-upstream branch-name origin/branch-name
在本地創(chuàng)建和遠程分支對應的分支,用git checkout -b branch-name origin/branch-name
標簽管理
tag打在版本庫中,和commit是聯(lián)系在一起的
先切換到需要打標簽的分支上,然后git tag<name>便可以新打一個標簽
用git tag可以查看所有的標簽
一般打標簽都是打在最新的commit上,如果忘了打的話,可以用git log --pretty=oneline --abbrev-commit查到commit-id之后用git tag vo.9 123456,然后用git tag查看標簽
git show<tag_name>查看標簽信息
git tag -a<tag_name> -m "abcdef..."可以創(chuàng)建帶有說明的tag
刪除標簽 git tag -d vo.1
因為創(chuàng)建的標簽在本地,不會上傳到遠程
推送tag到遠程 git push origin <tag_name>
一次性全部推送標簽git push origin --tags
刪除遠程標簽
- 第一步:
git tag -d<tag_name> - 第二步:
git push origin : refs/tags/<tag_name>
常見問題整理:
- 遇到
》符號說明沒有輸完ctrl + d - 幾種git add
-
git add a.txt匹配到a.txt -
git add *.txt匹配到當前目錄下所有txt -
git add A/*.txt匹配到當前目錄和子目錄下所有txt -
git add .匹配到當前目錄下所有文件
- 添加folder到repository
- git add <folder_name>
- git add folder_name/*
- git commit
- git push
- 刪除repo中文件而不刪除本地的
- remove folder/directory only from git repo and not from local
- step 1:
git rm -r --cached <file or folder name> - step 2:
git commit -m"removed folder from repo" - step 3:
git push origin <your git branch>
- step 1:
- remove folder/directory from repo & local
- step 1:
git rm -r <one of the directories> - step 2:
git commit -m"removed folder from repo" - step 3:
git push origin <your git branch>
- step 1: