1、 git(在git bash中操作)
明確一些git中的概念
1.1.git版本管理工具中四個區域概念:
(1)Workspace:工作區
(2)Stage:暫存區
(3)Repository:倉庫區(或本地倉庫)
(4)Remote:遠程倉庫
其中工作區和暫存區在各個不同的分支中是共享的(方便理解stash操作)
- git中一些單詞的大概意思
(1) HEAD 表示當前版本,上一個版本就是HEAD^(可以寫爲HEAD~1),上上一個版本就是HEAD^^^^^(可以寫爲HEAD~5),
- git中文件狀態
(1) untracked:新建的文件,沒有git add [filename] 的都屬於未被git追蹤到文件
(2) 未加入到暫存區的文件: 指的是已經被追蹤(tracked)過,但是沒有加入到暫存區(已經執行過git add的但是這次修改後還沒有git add)
- 遠程庫
(1) origin : git給遠程庫起的默認名稱是origin
- git init
git init 初始化git倉庫
git init [program-name] 新建一個目錄,將其初始化爲Git代碼庫
- git clone(默認 : clone下來的版本只能看到master分支, 如果,想要在dev分支上開發,就必須創建遠程
origin的dev分支到本地)
git clone [email protected]:yanqiangsjz/website.git 將遠程倉庫克隆到本地開發(多人協作開發)
git checkout -b [branch] [remote]/[branch] (創建遠程[remote]的[branch]分支到本地。 一般遠程倉庫和本地倉庫分支命名一樣)
- git config (--global參數是全局參數,也就是這些命令在這臺電腦的所有Git倉庫下都有用。 如果不加,那隻針對當前的倉庫起作用。)
git config --list 顯示當前的Git配置
git config user.name 查看用戶名
git config user.email
git config --global user.name [username] 設置全局用戶名
git config --global user.email [email]
git config --global color.ui true 配置Git顯示顏色
- git add
git add [filename] 添加指定文件到暫存區(表示添加新文件和編輯過的文件不包括刪除的文件)
git add [dir] 添加指定目錄到暫存區,包括子目錄
git add . 添加當前目錄的所有文件到暫存區(表示添加新文件和編輯過的文件不包括刪除的文件)
git add -u 表示添加編輯或者刪除的文件,不包括新添加的文件
- - git rm filename
git rm [filename] 刪除工作區文件並放進暫存區
如果想從暫存區撤銷:git reset HEAD -- [filename]
如果想撤銷工作區的修改:git checkout -- [filename]
注意區別 : rm [filename] 刪除工作區文件, 並沒有放進暫存區
如果想撤銷工作區的修改:git checkout -- [filename]
git rm --cached [filename] 停止追蹤文件,但該文件會保留在工作區(untracked狀態)
- - git diff
git diff [filename] 比較的是工作區文件與暫存區文件的差異
git diff --cached [filenam] 比較的是暫存區的文件與上一個commit的差異
git diff HEAD -- [filename] 比較的是工作區與當前分支最新commit之間的差異
- - git status
git status 查看文件狀態; 還可以在分支合併衝突的時候提示哪個文件衝突
- - git commit
git commit -m [message] 暫存區提交到倉庫區
git commit [filename1] [filename2] ... -m [message] 暫存區的指定文件提交到倉庫區
git commit -a -m [message] 工作區中修改後,還未使用git add . 命令添加到暫存區中的文件也一併提交上去
相當於git add . 與git commit –m [message] 兩句操作合併爲一句進行使用。commit完成過後,git status,
下方的工作區是乾淨的
- - git log
git log 查看當前分支的版本歷史
git log --stat 查看commit歷史,以及每次commit發生變更的文件
git log --pretty=oneline 查看從最近到最遠的提交日誌簡單日誌(--pretty=oneline:單行模式)
git log -1 查看最近一次的提交信息
git log -n 查看最近n次的提交信息
git log --graph 查看分支合併圖
git log --graph --pretty=oneline 查看分支合併圖;簡單日誌
git reflog 查看命令歷史,以便確定要回到未來的哪個版本
- - git blame
git blame [filename] 查看指定文件是什麼人在什麼時間修改過
- - git shortlog
git shortlog -sn 查看所有提交過的用戶,按提交次數排序
- - git show
git show [commit] 顯示某次提交時,文件變化
git show [commit]:[filename] 顯示某次提交時,某個文件的內容(注意[commit]:[filename]冒號之間沒有空格)
- - git checkout
git checkout -- [filename] 工作區filename的修改撤銷
git checkout . 撤銷工作區的全部修改
解釋 :一種是文件修改後還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態;
一種是文件已經添加到暫存區後,又作了修改,現在,撤銷修改就回到添加到暫存區後的狀態。
總之,就是讓這個文件回到最近一次git commit或git add時的狀態。
- - git checkout (2)
git checkout [branch] 切換分支
git checkout -b [branch] 創建並切換到該分支(如果在切換分支的時候,未commit, 有可能會報錯)
- - git checkout (3)
git checkout -b [branch] [remote]/[branch]
說明:
多人協作時,如果同事從遠程庫clone時,默認情況下,你的同事只能看到本地的master分支。如果,你的同事要在([branch])分支上開發,
就必須創建遠程([remote])的([branch])到本地
- - git reset (1)
git reset [filename] 重置暫存區的指定文件,與上一次commit保持一致,工作區不變
git reset --hard 重置暫存區與工作區,與上一次commit保持一致
git reset --hard HEAD~2 回退到某個版本(這裏是從當前版本回退兩個版本)
git reset --hard commitID 回退到某個版本(commitID是版本號)
- - git reset (2)
git reset HEAD -- [filename] 把暫存區的修改撤銷(unstage),重新放回工作區
- - git branch 分支名稱
git branch [branch] 創建分支
git branch 列出所有本地分支
git branch -a 列出所有本地分支和遠程分支
git branch -r 列出所有遠程分支
git branch -d [branch] 刪除分支
git branch -D [branch] 強制刪除一個還沒有合併(已經commit)的分支
說明:
1、如果一個分支在開發完成以後(分支已經commit)待合併,如果出於某種原因這個分支廢棄了,但是這個分支必須刪除。git branch -D [branch]
2、如果一個分支還沒有commit, 是可以使用 git branch -d [branch]
- git merge (merge之前必須都先commit,即工作區和暫存區使用git status 應該是乾淨的工作區域,即是已經是最新的commit)
git merge [branch] 合併指定分支([branch])到當前分支
git merge --no-ff -m [message] [branch] 合併指定分支([branch])到當前分支,禁用Fast forward模式
解釋 : 禁用Fast forward模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息。
必要 : 如果merge出現衝突, 則解決衝突以後必須:1、git add 2、git commit。
建議 :
(1 解決完成衝突以後,最好直接將分支刪除,如果需要,再新建一條分支。原因是在解決衝突了以後,如果還切換回之前的分支繼續開發,
分支還是衝突發生前的內容(解決衝突只解決的主分支master的(而且衝突解決不是全部按照分支內容解決的)所以再次提交會報錯。
(2 如果合併衝突完全放棄原來主分支的衝突採用dev分支的內容,則合併後主分支的內容和現存在dev分支是一樣的內容,不刪除原來的分
支繼續在上面開發也是可以的
衝突判定機制 : 先尋找兩個commit的公共祖先,比較同一個文件分別在ours和theirs下對於公共祖先的差異,然後合併這兩組差異如果
雙方同時修改了一處地方且修改內容不同,就判定爲合併衝突,依次輸出雙方修改的內容
分支策略 : 首先,master分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面幹活;那在哪幹活呢?幹活都在dev分支上,
也就是說,dev分支是不穩定的,到某個時候,比如1.0版本發佈時,再把dev分支合併到master上,在master分支發佈1.0版本;每個人
都在dev分支上幹活,每個人都有自己的分支,時不時地往dev分支上合併就可以了。
補充建議 : 如果在dev分支上正在開發一個功能,但是這是master上需要解決一個bug,這時需要切換回master在開發出一個bug分支 來解決
這個bug,但是在dev分支上功能還沒有開發完,不能commit。這時解決辦法是:第一步、將dev分支上的工作現場 ‘封存’起來(git stash)
第二步、 切換到主分支,新建主分支的bug分支,將bug修改完然後切換回主分支將bug分支合併。 第三部、 切換回dev分支,將bug分支同時
合併到dev分支(原因是 : 避免是如果bug分支上修改的東西太多,在最後 dev開發完成以後,master合併dev分支的時候出現大面積的衝突)
- - git stash
git stash list 查看使用儲藏起來的工作現場
git stash apply 恢復工作現場(但是stash內容並不刪除)
git stash drop 刪除stash內容
git stash pop 恢復工作現場並刪除stash內容
說明:
git stash 只能“儲藏”已被追蹤過的文件。意思就是說如果是新添加的文件還沒有執行過`git add`的文件,在使用git stash後還是會在工作區中出現,
並不會別“儲藏”。所以要使用git stash, 請將untrack狀態的文件執行git add, 使其可被git追蹤
git stash 把當前工作現場“儲藏”起來(如果在一個分支上修改了文件但是因爲還沒有修改完不能提交的時候, 如果要開發出一個新的分支解決一個問題,
如果不使用git stash, 那麼在另一個分支上也是可以看到這個分支上修改的內容。)
結論 :
1.工作區和暫存區是共用的,在各個分支裏都可以看到沒被stash的文件。
2.在工作區和暫存區的文件都可以stash,pop之後都會出現在工作區
說明 : 假設在dev分支上正在開發,忽然程序出現bug,需要即刻修復,但是dev分支上的任務還沒有完成,無法提交合併到master。
但是現在就需要在master上創建一個分支bugs去修復這個問題。因爲工作區和暫存區對所有分支默認都是共用的,所以在bugs分支
上會執行dev分支上未完成的修改。這樣是不允許的。所以我們可以在dev分支中git stash 將dev分支
中的工作區和暫存區隱藏起來,這樣在別的分支中就看不到dev分支工作區中和暫存區中的已有的工作,這意味着工作區是乾淨的。我們可以在
bugs分支中可以看到工作區是乾淨的,可以執行任意我們的任務。等待bugs分支開發完成,再切換到master分支,接着將bugs分支merge
到master。但是現在我們思考一下,現在主分支是最新的(修復了bugs並且merge上去的),但是我們的dev分支卻還是和未修復bugs的
master主分支同步的版本。如果這樣的話,在我們開發完dev分支並且合併到master分支上時,就有可鞥會出現問題(除非是增加文件,否則就
會出現合併衝突)。如果我們的dev分支版本現在不存在master中存在的bug,則我們完全可以放心。但是如果dev中也會出現像master
中出現的bug,則當我們將dev合併到master中時,還是會出現同樣的bug。主要是在這種情況下,還會發生合併時候衝突。所以在將bugs
合併到master以後,我們也可以選擇將bugs分支合併到dev分支中,合併完成之後,現在master和dev中的代碼是一樣的。但是我們之前
在dev中執行了git stash, 還有“儲藏”的工作區中已經開發但未提交的內容,當我們執行git stash pop 恢復之前的工作現場並刪除
stash內容,會發現有衝突發生了(因爲現在dev分支和master分支是一樣的,現在該文件是已經修復完成的, 但是我們釋放的工作區中之前就對
該文件做了修改:同一個文件不同的內容,這樣就會明顯的出現衝突)。這是我們就需要解決這些衝突(其實就是將之前修改的刪掉,保留和現在
master主分支中的文件一樣的信息)。解決完成以後。我們就完全解決了以後dev合併到master中可能存在的衝突,並且在合併以後不會再出現同樣
的錯誤
- - git remote (git給遠程庫起的默認名稱是origin)
git remote -v 查看遠程庫的信息
git remote show [remote] 顯示某個遠程倉庫的信息
git remote add [remote] [url] 增加一個新的遠程倉庫,並命名 (一般是origin)
git remote rm [remote] 刪除遠程庫
- - git push
git push [remote] master 將主分支推送到遠程庫
git push [remote] [branch] 將([branch])分支推送到遠程庫
git push [remote] --delete [branch] 刪除遠程分支
git push [remote] [tagname] 推送某個標籤到遠程
git push [remote] --tags 一次性推送全部尚未推送到遠程的本地標籤
- git pull origin 分支名稱 (取回遠程倉庫的變化,並與本地分支合併)
git pull [remote] [branch] 取回遠程倉庫的變化,並與本地分支合併
說明 : 在向遠程庫推送某個分支的時候,需要先"Git pull"更新本地的代碼
即 : 如果你的同事先在dev分支推送他的提交,接下來你去推送很有可能會失敗。因爲你的同事最新提交和你試圖推送的提交有衝突,
解決辦法也很簡單,Git已經提示我們,先用git pull把最新的提交從origin/dev抓下來,然後,在本地合併,解決衝突,
git add -> git commit -> 再推送
如果: git pull 也失敗了 :
$ git pull
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 2), reused 8 (delta 2), pack-reused 0
Unpacking objects: 100% (8/8), done.
From github.com:yanqiangsjz/rhjt
6876a33..e2516f8 oneline -> origin/oneline
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/<branch> oneline
原因 : 沒有指定本地dev分支與遠程origin/dev分支的鏈接,根據提示,設置dev和origin/dev的鏈接:git branch --set-upstream-to=origin/dev dev
git pull --rebase origin master 遠程庫同步到本地庫 (解決的問題:error: failed to push some refs to ‘[email protected]:name/project.git’)
- git branch --set-upstream-to=origin/dev dev
git branch --set-upstream-to=origin/dev dev 設置dev和origin/dev的鏈接。成功以後就可以git pull
- - git tag
git tag [tagname] 爲當前HEAD打標籤(本地tag)
git tag [tagname] commitId(commitId 默認未HEAD; 本地tag)
git tag -a [tagname] -m [message] commitId 爲本地tag添加說明
git tag 查看所有標籤信息
git show [tagname] 查看某個tag信息
git tag -d [tagname] 刪除本地標籤
- - 刪除遠程標籤
git tag -d [tagname] -> git push [remote] :refs/tags/[tagname]
說明:git tag -d [tagname](先從本地刪除); git push [remote] :refs/tags/[tagname](然後,從遠程刪除)
- - git checkout -b [branch] [tag]
git checkout -b[branch] [tagname] 新建一個分支,指向某個tag
- git fetch (取回遠程倉庫的變化,但並不會主動與本地分支合併。這個比git pull 更安全)
//方法一 例子
git fetch origin master //從遠程的origin倉庫的master分支下載代碼到本地的origin master
git log -p master.. origin/master//比較本地的倉庫和遠程參考的區別
git merge origin/master//把遠程下載下來的代碼合併到本地倉庫,遠程的和本地的合併
//方法二
git fetch origin master:temp //從遠程的origin倉庫的master分支下載到本地並新建一個分支temp
git diff temp//比較master分支和temp分支的不同
git merge temp//合併temp分支到master分支
git branch -d temp//刪除temp
## 2. gitHub ##
- 將本地git倉庫同步到github上
1. git remote add [remote] [url]
2. git push -u [remote] [branch] (指定[remote]爲默認主機)
3. 以後修改提交到遠程庫直接git push [remote] [branch]就可以了 (不帶任何參數的git push,默認只推送當前分支)
## 3、 git自定義
- 忽略特殊文件
有些時候,你必須把某些文件放到Git工作目錄中,但又不能提交它們,比如保存了數據庫密碼的配置文件啦,等等,
每次git status都會顯示Untracked files ...,有強迫症的童鞋心裏肯定不爽。好在Git考慮到了大家的感受,
這個問題解決起來也很簡單,在Git工作區的根目錄下創建一個特殊的.gitignore文件,然後把要忽略的文件名填
進去,Git就會自動忽略這些文件不需要從頭寫.gitignore文件,GitHub已經爲我們準備了各種配置文件,
只需要組合一下就可以使用了。所有配置文件可以直接在線瀏覽. 查看請點擊下面的鏈接
[https://github.com/github/gitignore](https://github.com/github/gitignore "github")
- 配置別名(--global參數是全局參數,也就是這些命令在這臺電腦的所有Git倉庫下都有用,針對當前用戶。如果不加,那隻針對當前的倉庫起作用。)
git config --global alias.st status (爲查看狀態配置別名)
git config --global alias.last 'log -1' (爲顯示最後一次提交信息配置別名)
git config --global alias.unstage 'reset HEAD' (爲暫存區的修改撤銷回工作區配置別名)
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
那麼配置文件放在哪裏呢:
(1) 每個倉庫的Git配置文件都放在.git/config文件中
(2) 當前用戶的Git配置文件放在用戶主目錄下的一個隱藏文件.gitconfig中
(3) 我們可以直接在配置文件中進行配置
- git 上傳項目到github一般流程
1、本地項目git init -> git add . -> git commit -m '註釋'
2、在github上創建項目
3、git remote add [remote] [url]
4、如果在github上創建的項目不包含README.md(即使一個空文件夾),則
git push -u origin master 直接就可以了
5、如果在github上創建的項目包含README.md,但是在本地的文件夾中
沒有這個文件, 首先 git pull --rebase origin master(依照遠程庫README.md內容爲準)
將遠程庫同步到本地庫,然後 git push -u origin master 就可以了
6、如果在github上創建的項目包含README.md, 本地文件夾中也包含這個文件,則
git pull origin master --allow-unrelated-histories,然後如果發現有
衝突則解決衝突(也可以使用git fetch origin master --allow-unrelated-histories,
然後手動 git merge origin/master), 然後git add README.md, git commit -m '註釋',
最後 git push -u origin master
- pwd(linux命令)
pwd 顯示當前目錄