專欄詳情
GIT介紹
Git ( git-scm.com/ ) 是開源的分佈式版本控制系統, 是 Linus Torvalds 爲幫助開發人員而設計的軟件系統, 在開發人員中大部分會選擇Git作爲你的代碼管理工具。
- 分支: 從主分支(master)上分離出來的子分支, 從而進行不影響master分支的操作
- 合併: 你在子分支的修改需要歸併到master的時候就需要將分支合併
- 衝突: 在不同分支對同一文件修改提交後合併會產生衝突, 需要手動解決, 具體體現是在文件內容衝突的地方寫入內容差異
- 倉庫: 倉庫是你提交代碼後保存代碼的地方, 我們會有遠程倉庫和本地倉庫之說
GIT差異
Git和其他版本控制系統的主要差別在於Git只關心文件數據的整體是否發生變化, 而大多數其他系統則只關心文件內容的具體差異, 這類系統(CVS | Subversion | Perforce | Bazaar...)每次記錄有哪些文件作了更新以及更新的內容。
Git並不保存這些前後變化的差異數據, 而Git更像是把變化的文件作快照後記錄在一個內置文件系統中, 每次提交更新時它會縱覽所有文件的指紋信息並對文件作快照, 然後保存一個指向這次快照的索引, 若文件沒有變化, 僅僅是保存上次的快照鏈接。
在Git中的絕大多數操作都只需要訪問本地文件和資源而不用連接網絡, 但如果用CVCS的話, 差不多所有操作都需要連接網絡, 因爲Git在本地磁盤上就保存着所有當前項目的歷史提交, 所以處理速度極快。
數據在保存到Git之前, 所有數據都要進行內容的校驗和計算(checksum), 並將此結果作爲數據的唯一標識和索引, 換句話說, Git不可能在你修改了文件或目錄之後對此一無所知。 這項特性作爲Git的設計哲學, 建在整體架構的最底層, 所以如果文件在傳輸時變得不完整或者磁盤損壞導致文件數據缺失時Git都能立即察覺。 而Git使用 SHA-1 算法計算數據的校驗和, 通過對文件的內容或目錄的結構計算出一個SHA-1哈希值, 作爲指紋字符串, 該字串由 40 個十六進制字符(0-9 | a-f)組成, 實際上所有保存在Git數據庫中的東西都是用此哈希值來作索引的, 而不是靠文件名。
對於任何一個文件, 在Git內都只有三種狀態:
- 已提交 (committed): 表示該文件已經被安全地保存在本地數據庫中
- 已修改 (modified): 表示修改了某個文件但還沒有提交保存
- 已暫存 (staged): 表示把已修改的文件放在下次提交時要保存的清單中
由此我們看到Git管理項目時, 文件流轉的三個工作區域: 工作目錄 | 暫存區域 | 本地倉庫
GIT命令
在三個工作區的基礎上, 我們實際還有一個 遠程倉庫區, 跟本地倉庫一樣, 只是倉庫位置從本機拓展到了遠程服務器上。
Command | Descriptions |
---|---|
git add -i | 打開一個交互式界面按需求添加文件 |
git add -p | 對同一個文件的多處變化分次提交 |
git add -u | 將本地的(修改, 刪除, 沒有新增)文件添加到暫存區 |
git add . git add -A |
添加當前目錄的所有文件到暫存區 |
git add [DirName] | 添加指定目錄到暫存區 |
git add [FileName] ... | 添加指定文件到暫存區 |
git archive | 生成一個可供發佈的壓縮包 |
git blame [FileName] | 顯示指定文件是什麼人在什麼時間修改的信息 |
git branch --set-upstream [Branch] [RemoteBranch] | 建立追蹤關係, 在現有分支與指定的遠程分支之間 |
git branch --track [Branch] [RemoteBranch] | 新建一個分支, 與指定的遠程分支建立追蹤關係 |
git branch -a | 列出所有分支 |
git branch -d [Branch] | 強制刪除分支 |
git branch -m [OldName] [NewName] | 本地分支重命名 |
git branch -r | 列出所有遠程分支 |
git branch [Branch] [Commit] | 新建一個分支, 指向指定commit |
git branch [Branch] | 新建一個分支, 但不切換 |
git branch | 查看本地所有分支 |
git checkout - | 切換到上一個分支 |
git checkout --track origin/dev | 切換到遠程dev分支 |
git checkout -b [Branch] [tag] | 新建一個分支, 指向某個tag |
git checkout -b [Branch] | 新建一個分支, 並切換到該分支 |
git checkout . | 恢復暫存區的所有文件到工作區 |
git checkout [Branch] | 切換到指定分支, 並更新工作區 |
git checkout [Commit] [File] | 恢復某個commit的指定文件到暫存區和工作區 |
git checkout [FileName] | 恢復暫存區的指定文件到工作區 |
git checkout [BranchName] | 切換分支 |
git cherry-pick [CommitID] | 用於把另一個本地分支的commit修改應用到當前分支 |
git clone [URL] | 克隆對應項目URL的代碼到本地 |
git commit --amend -m [message] | 代碼沒有任何新變化, 則改寫上一次commit的提交信息 |
git commit --amend [file1] [file2] ... | 重改上一次commit, 幷包括指定文件的新變化 |
git commit -a -v | 一般提交命令 |
git commit -a | 提交當前repos的所有的改變 |
git commit -am [message] | 提交工作區變化的文件直接到倉庫區, 並添加提交描述信息 |
git commit -m [message] | 提交暫存區到倉庫區, 並添加提交描述信息 |
git commit -v | 提交時顯示所有diff信息 |
git commit [file1] [file2] ... -m [message] | 提交暫存區的指定文件到倉庫區, 並添加提交描述信息 |
git commit | 提交 |
git config --global alias.ci commit git config --global alias.co checkout |
設置git命令的別名 |
git config --list | 顯示Git配置 |
git config -e [--global] | 編輯Git配置文件 |
git config -l | 查看當前配置 |
git config [--global] user.name "[userName]" git config [--global] user.email "[email]" |
設置用戶信息 |
git diff --cached [file] | 顯示暫存區和上一個commit的差異 |
git diff --cached git diff --staged |
查看尚未提交的更新 |
git diff --shortstat "@{0 day ago}" | 顯示今天你寫了多少行代碼 |
git diff --staged | 查看暫存起來的文件(stage)與並未提交(commit)的差別 |
git diff --stat | 查看顯示簡略結果(文件列表) |
git diff HEAD | 顯示工作區與當前分支最新commit之間的差異 |
git diff [first-branch]...[second-branch] | 顯示兩次提交之間的差異 |
git diff | 顯示暫存區和工作區的差異 |
git fetch [remote] | 下載遠程倉庫的所有變動 |
git fetch | 從遠程獲取最新版本到本地, 不會自動merge |
git init [dirName] | 新建一個目錄並初始化爲Git本地倉庫 |
git init | 在當前目錄創建一個Git本地倉庫 |
git log --follow [file] git whatchanged [file] |
顯示某個文件的版本歷史, 包括文件改名 |
git log --graph | 顯示何時出現了分支和合並等信息 |
git log --oneline | 一行顯示一條log |
git log --stat | 顯示commit歷史, 以及每次commit發生變更的文件 |
git log -3 | 查看前3次修改 |
git log -N --pretty --oneline | 顯示過去N次提交 |
git log -S [keyword] | 搜索提交歷史, 根據關鍵詞 |
git log -p [file] | 顯示指定文件相關的每一次diff |
git log -p | 查看詳細修改內容 |
git log [tag] HEAD --grep feature | 顯示某個commit之後的所有變動, 其"提交說明"必須符合搜索條件 |
git log [tag] HEAD --pretty=format:%s | 顯示某個commit之後的所有變動, 每個commit佔據一行 |
git log | 顯示當前分支的版本歷史 |
git ls-files | 看已經被提交的 |
git merge --abort | 儘量回退到merge前的狀態(可能會失敗) |
git merge --no-ff <branch_name> | 採用no fast forward的合併方式, 這種方式在合併的同時會生成一個新的commit |
git merge --squash <branch_name> | 將目標分支合併過來但不攜帶commit信息, 執行後最後需要提交一個commit |
git merge [branch] | 合併指定分支到當前分支 |
git mv [file-original] [file-renamed] | 修改文件名, 並且將這個改名放入暫存區 |
git pull --rebase | 暫存本地變更, 合併遠程最新改動, 合併剛剛暫存的本地變更(不產生無用的merge的同步) |
git pull [remoteName] [localBranchName] | 拉取遠程倉庫 |
git pull origin --tags | 合併遠程倉庫的tag到本地 |
git pull | 從遠程獲取最新版本並merge到本地 |
git push --all origin | 將所有本地分支都推送到origin主 |
git push -f origin | -f強推, 在遠程主機產生一個"非直進式"的合併(non-fast-forward merge) |
git push -u origin master | -u指定origin爲默認主機, 後面就可以不加任何參數使用git push了 |
git push [remoteName] --delete [branch] git branch -dr [remote/branch] |
刪除遠程分支 |
git push [remoteName] :refs/tags/[tagName] | 刪除遠程tag |
git push [remoteName] [localBranchName] | 推送遠程倉庫 |
git push [remote] --all | 推送所有分支到遠程倉庫 |
git push [remote] --force | 強行推送當前分支到遠程倉庫, 即使有衝突 |
git push [remote] --tags | 提交所有tag |
git push [remote] [branch] | 上傳本地指定分支到遠程倉庫 |
git push [remote] [tag] | 提交指定tag |
git push origin --tags | 上傳本地tag到遠程倉庫 |
git push origin :heads/[name] git push origin :[name] |
刪除遠程分支 |
git push origin :refs/tags/[name] | 刪除遠程版本 |
git push origin master:hb-dev | 將本地庫與服務器上的庫進行關聯 |
git rebase --abort | 終止rebase, 分支會回到rebase開始前的狀態 |
git rebase --continue | 執行rebase出現衝突解決後, 執行該命令會繼續應用(apply)餘下的補丁 |
git rebase --skip | 跳過當前提交 |
git reflog | 顯示當前分支的最近幾次提交 |
git remote -v | 顯示所有遠程倉庫 |
git remote add [shortname] [url] | 增加一個新的遠程倉庫, 並命名 |
git remote rm [name] | 刪除遠程倉庫 |
git remote set-url --push [name] [newUrl] | 修改遠程倉庫 |
git remote show [remote] | 顯示某個遠程倉庫的信息 |
git remote show | 查看遠程庫 |
git reset --hard [commit] | 重置當前分支的HEAD爲指定commit, 同時重置暫存區和工作區, 與指定commit一致 |
git reset --hard | 徹底回退到某個版本, 替換暫存區和工作區, 本地的源碼也會變爲上一個版本的內容 |
git reset --keep [commit] | 重置當前HEAD爲指定commit, 但保持暫存區和工作區不變 |
git reset --mixed | 同不帶任何參數的git reset一樣, 重置暫存區, 但不改變工作區 |
git reset --soft HEAD~3 | 引用回退三次(工作區不變, 暫存區不變) |
git reset --soft | 回退到某個版本, 不改變暫存區和工作區(如果還要提交, 直接commit即可 |
git reset HEAD | HEAD 效果同上, 因爲引用重置到HEAD相當與沒有重置 |
git reset HEAD^ | 引用回退一次(工作區不變, 暫存區回退) |
git reset [commit] | 重置當前分支的指針爲指定commit, 同時重置暫存區, 但工作區不變 |
git reset [file] | 重置暫存區的指定文件, 與上一次commit保持一致, 但工作區不變 |
git reset | 將之前用git add命令添加到暫存區的內容撤出暫存區(相當於git add -A 的反向操作) |
git revert -n HEAD | 撤銷上一次但不commit |
git revert -no-edit HEAD | 撤銷上一次並直接使用默認註釋 |
git revert HEAD | 撤銷上一次commit |
git revert [commit] | 新建一個commit, 用來撤銷指定commit 後者的所有變化都將被前者抵消, 並且應用到當前分支 |
git rm --cached [file] | 停止追蹤指定文件, 但該文件會繼續保留在工作區 |
git rm -r [floder] | 刪除文件夾 |
git rm [file1] [file2] ... | 刪除工作區文件, 並且將這次刪除操作放入暫存區 |
git shortlog -sn | 顯示所有提交過的用戶, 按提交次數排序 |
git show --name-only [commit] | 顯示某次提交發生變化的文件 |
git show [commit] | 顯示某次提交的元數據和內容變化 |
git show [commit]:[filename] | 顯示某次提交時, 某個文件的內容 |
git show [tag] | 查看tag信息 |
git stash apply | 恢復最新保存工作進度, 但不刪除 |
git stash clear | 刪除所有 |
git stash drop | 刪除一個進度, 默認刪除最新的 |
git stash list | 顯示進度列表 |
git stash pop | 恢復最新保存的工作進度, 並將恢復的工作進度從存儲的列表中刪除 |
git stash push | 將文件給push到一個臨時空間中 |
git stash save "message" | 保存進度加說明 |
git stash | 保存當前的工作進度 |
git status --ignored | 顯示被忽略的文件 |
git status -s | 將結果以簡短的形式輸出 |
git status | 查看當前狀態 |
git submodule add [url] [path] | 添加子模塊 |
git submodule init | 初始化子模塊 |
git submodule update | 更新子模塊 |
git tag -a [name] -m 'yourMessage' | 創建帶註釋的tag |
git tag -d [tag] | 刪除本地tag |
git tag -r | 查看遠程版本 |
git tag [name] | 創建版本 |
git tag [tag] [commit] | 新建一個tag在指定commit |
git tag [tag] | 新建一個tag在當前commit |
git tag | 列出所有tag |
git version | 獲取git版本 |
常見錯誤
認證失敗
# 方案一
git config --system --unset credential.helper
# 方案二
-> win+R 打開命令窗口
-> 輸入 control
-> 用戶賬戶
-> 管理你的憑據
-> Windows憑據
-> 找到Git地址的對應憑據修改賬戶密碼