git克隆 不带目录_Git 系统学习笔记
公眾號內發送Git獲取Git官方PDF教程
版本控制
版本控制是一種記錄一個或若干個文件內容變化、以便將來查閱特定版本修訂情況的系統。
本地版本控制系統
很久以前就開發了許多本地版本控制系統、大多都是采用某種簡單的數據庫來記錄文件的歷次更新差異。
其中最流行的一種叫做 RCS、現今許多計算機系統上都還看得到他的蹤影。RCS 的工作原理是在硬盤上保存補丁集、通過應用所有的補丁、可以重新計算出各個版本的文件內容。
集中化版本控制系統
讓不同系統上的開發者協同工作、集中化版本控制系統應運而生。有一個單一的集中管理的服務器、保存所有文件的修訂版本、而協同工作的人們都通過客戶端連到這臺服務器、取出最新的文件或者提交更新。
壞處
- 單點故障
- 無備份
分布式版本控制系統
在分布式版本控制系統中、客戶端不只是提取最新版本的文件快照、而是把代碼倉庫完整地鏡像下來、包括完整的歷史記錄。
這么一來、任何一處協同工作用的服務器發生故障、事后都可以用任何一個鏡像出來的本地倉庫恢復。
Git 簡史
Git 的設計目標
- 速度
- 簡單的設計
- 對非線性開發模式的強力支持(允許成千上萬個并行開發分支)
- 完全分布式
- 有能力高效管理類似 Linux 內核一樣的超大規模項目
直接記錄快照、而非差異比較
Git 喝其他版本控制系統(Subversion) 的主要差別在于 Git 對待數據的方法。
從概念上來說、其他大部分系統以文件變更列表的方式存儲信息、這類系統將它們存儲的信息看作是一組基本文件喝每個文件隨時間逐步累積的差異,稱之為基于差異的版本控制
Git 不按照以上方式對待或保存數據、Git 更像是把數據看作是對小型文件系統的一系列快照。在 Git 中、每當你提交更新或保存項目狀態時、它基本上就會對當時的全部文件創建一個快照并保存這個快照的索引。為了效率、如果文件沒有修改、Git 則不再重新存儲文件、只是保留一個指向之前存儲的文件。Git 對待數據更像是一個快照流。
Git 幾乎與所有其他版本控制系統的重要區別就是在于這個地方。
近乎所有操作都是本地執行
在 Git 中絕大多數操作都只需要訪問本地文件和資源、一般不需要來自網絡上其他計算機的信息。
Git 保證完整性
Git 中所有的數據在存儲前都計算檢驗和、然后以檢驗和來飲用。
Git 用以計算校驗和的機制叫做 SHA-1 散列。是由 40 個十六進制自發組成的字符串、基于 Git 中文件內容或目錄結構計算出來的。
Git 一般只添加數據
你執行的 Git 操作、幾乎只往 Git 數據庫中添加數據
三種狀態
Git 有三種狀態、你的文件可能處于其中的一種
- 已修改
表示修改了文件、但沒保存到數據庫中 - 已暫存
表示對一個已修改文件到當前版本做了標記、使之在下次提交到快照中 - 已提交
表示數據已經安全地保存在本地數據庫中。
這會讓我們的 Git 項目擁有三個階段:工作區、暫存區、Git 目錄。
工作區是對項目的某個版本獨立提取出來的內容。這些從 Git 倉庫的壓縮數據庫中提取出來的文件、放在磁盤供你使用或修改。
暫存區是一個文件、保存了下次將要提交的文件列表信息、一般在 Git 倉庫目錄中。按照 Git 的術語叫做“索引”。
Git 倉庫目錄是 Git 用來保存項目的元數據和對象數據庫的地方。這是Git 中最重要的部分。從其他計算機克隆倉庫時、復制的就是這里的數據。
基本的 Git 工作流程如下
- 在工作區中修改文件
- 將你想要下次提交的更改選擇性地暫存、這樣只會將更改的部分添加到暫存區。
- 提交更新、找到暫存區的文件、將快照永久性存儲到 Git 目錄。
Git 初次接觸
查看版本&查看配置
git --version
git config --list
// 查看單獨某項配置
git config user.name
配置
git config --global user.name "coderLi"
git config --global user.email "coderLi@xxx.com"
如果使用了 --global 選項、那么該命令只需要運行一次、因為之后無論你在該系統上做任何事情、Git 都會使用那些信息。
由于 Git 會從多個文件中讀取同一配置的變量的不同值。可以通過查詢 Git 中該變量的原始值、它會告訴你哪一個配置文件最后設置了該值
git config --show-origin user.name
file:/Users/coderLi/.gitconfig coderLi
獲取幫助
git help <verb>
git <verb>--help
man git-<verb>
git add -h
Git 基礎
- 配置并初始化一個倉庫
- 開始或停止跟蹤文件
- 暫存或提交更改
獲取倉庫
獲取 Git 倉庫通常有兩種方式
- 將尚未進行版本控制的本地目錄轉為 Git 倉庫
- 從其他服務器克隆一個已存在的 Git 倉庫
初始化倉庫
cd /Users/user/my-project
git init
該命令創建一個名為 .git 的字幕了、這個子目錄有你初始化 Git 倉庫中所有的必須文件、這些文件是 Git 的倉庫骨干。
如果該文件夾下有問價需要進行版本控制、你應該開始追蹤這些文件并進行初始提交。
可以通過 git add 命令來制定所需的文件進行追蹤、然后執行 git commit
git add *.java
git add readme.md
git commit -m 'initial project version'
克隆現有的倉庫
這時就要使用 Git clone 命令、如果你對其他 VCS很熟悉、請留意一下你所使用的命令是 “clone” 而不是 “checkout” 。這是 Git 區別于其他吧版本控制系統的一個重要特性、Git 克隆的是 Git倉庫服務器上的幾乎所有數據、而不是僅僅復制完成你的工作所需要的文件。當執行 git clone 命令時、默認配置下原創 Git 倉庫中的每一個文件的每一個版本都將被拉取下來。事實上、如果你的服務器磁盤壞掉了、你通常可以使用任何一個克隆下來的用戶端重建服務器上的倉庫
# git clone <url>
git clone https://github.com/libgit2/libgit2
會在當前目錄下創建一個名為 libgit2 的目錄、并在這個目錄下初始化一個.git 文件夾、從遠程倉庫拉取下所有數據放入.git 文佳佳、然后從中讀取最新版本的文件拷貝。如果你進入到新建的這個libgit2 文件夾中、你會發現所有的項目文件已經在里面了、準備就緒等后續開發和使用。
如果你想自定義本地倉庫等名字、可以通過額外參數指定
git clone https://github.com/libgit2/libgit2 mylibgit
本地倉庫名就變為了 mylibgit
記錄每次更新到倉庫
工作目錄下的每個文件都不外乎這兩種狀態:
- 已跟蹤、是指那些被納入了版本控制的文件、在上一次快照中有它們的記錄、在工作一段時間之后、它們的狀態可能是未修改、已修改或已經放入暫存區。簡而言之、已跟蹤的文件就是 GIt 已經知道的文件
- 工作目錄中除已跟蹤文件外其他的文件都屬于未跟蹤文件、它們既不存在上一次的快照中、也米有被放入暫存區。初次克隆某個倉庫時、工作目錄中的所有文件都屬于已跟蹤文件、并處于未修改狀態
檢測當前文件狀態
git status 命令產看哪些文件處于什么狀態
跟蹤新文件
git add README
使用 git add 開始跟蹤一個文件、并將其放入到暫存區。如果此時提交、那么該文件在你運行 git add 時的版本將被留存在后續的歷史記錄中。git add 命令使用文件或目錄的路徑作為參數、如果參數時目錄的路徑、該命令將遞歸地跟蹤該目錄下的所有文件
暫存已修改的文件
git add 是一個多功能命令、可以用它來跟蹤新文件、或者把已跟蹤的文件放入暫存區、還能用于合并時把有沖突的文件標為已解決狀態。
這個命令可以理解為:精確地將內容添加到下一次提交中。
狀態概覽
git status 命令輸出十分詳細、但其用于有些繁瑣、使用 git status -s 簡化輸出方式
忽略文件
一般我們總有一些文件無需納入 Git 的管理、也不希望它們出現在未跟蹤文件列表中。在這種情況下、我們可以創建一個名為.gitignore的文件、列出要忽略的文件的模式。
*.[oa]
*~
第一行告訴 Git 忽略所有以.o或.a 結尾的文件。
第二行告訴我們忽略所有名字以~結尾的文件。
查看已暫存和未暫存的修改
git diff 比較的是工作目錄中當前文件和暫存區快照之間的差異、也就是修改之后還沒暫存起來的變化內容。
若要查看已暫存的將要添加都下次提交里的內容、可以使用 git diff --staged 命令、git diff --cached
需要注意的是、git diff 本身只現實尚未暫存的改動、而不是自上次提交以來所做的所有改動。所以如果你一下子暫存了所有更新過的文件、運行 git diff 后卻什么也沒有、就是這個原因。
提交更新
現在暫存區已經準備就緒、可以提交了。
git commit -m 'information'
跳過使用暫存區
盡管使用暫存區域的方式可以精心準備要提交的細節、但有時候這么做顯得繁瑣、Git 提供了一個跳過使用暫存區域的方式、只要在提交時、在 git commit 加上 -a 選項、Git 就會自動把所有已經追蹤過的文件暫存起來一并提交、從而逃過 git add 步驟。
移除文件
從 Git 中移除某個文件、就必須從暫存區中移除、然后提交。git rm 命令可以完成此項工作、并連帶從工作目錄中刪除置頂文件、這樣以后就不會出現在未跟蹤文件清單中了。
$ls
DijkstraJourneyGeneratorTest.java cassandra redis
Generic.java ehcache repository
$git rm Generic.java
$git status
Changes to be committed:(use "git restore --staged <file>..." to unstage)deleted: Generic.java
如果只是單純的在工作目錄中刪除文件、而沒有對齊進行提交、是不能在 Git 中刪除該文件的
$ls
DijkstraJourneyGeneratorTest.java cassandra redis
Generic.java ehcache repository
$rm Generic.java
$git status
Changes not staged for commit:(use "git add/rm <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)deleted: Generic.java這個時候你還是要執行 git rm Generic.java 來將這個刪除添加到暫存區
如果要刪除已經放到暫存區的文件、則必須使用強制刪除項 -f
$ vi Generic.java
$ git add Generic.java
第一步我們修改了 Generic.java 這個文件、然后將其放入到暫存區、但是這個時候我們想刪除這個 Generic.java 文件并且想將此次提交到暫存區的版本也刪除掉
$git rm -f Generic.java
$git status
Changes to be committed:(use "git restore --staged <file>..." to unstage)deleted: Generic.java
這個時候、我們工作目錄下也刪除了 Generic.java 的問價、并且剛剛修改Generic.java的版本也在暫存區中刪除了。
移動文件
git mv file_from file_to$git mv Generic.java Generic01.java
$git status
Changes to be committed:(use "git restore --staged <file>..." to unstage)renamed: Generic.java -> Generic01.java
其實運行 git mv就相當于運行了下面三條命了
$mv Generic.java Generic01.java
$git rm Generic.java
$git add Generic01.java
查看提交歷史
git log 在不傳入任何參數的默認情況下、git log 會按時間先后順序列出所有的提交、最精的更新排在最上面。
git log 有很多選項幫助你搜尋你所要查找的提交、其中最有用的就是 -p/-patch 選項、它會顯示每次提交所引入的差異(按補丁格式顯示)。
也可以限制顯示日志的條目數量、例如使用 -2 顯示最近的兩次提交。
撤銷操作
在任何一個階段、你都有可能想要撤銷某些操作。有時候我們提交完了才發現漏掉了幾個文件沒有添加、或者提交信息寫錯了、此時、可以使用帶有 --amend 選項來提交命令重新提交
git commit -m 'renew' -amend
這個命令會將暫存區中的文件提交、如果自上次提交以來你還未做任何修改、那么快照將會保持不變、而你修改的只是提交信息。
最終只會有一個提交、而第二次提交將會代替第一次提交的結果。 第一次的提交就像從未存在過一、它并不會出現在倉庫的歷史中。
取消暫存的文件
git add -A
git status
Changes to be committed:(use "git restore --staged <file>..." to unstage)..........
我們可以使用該命令將暫存區的版本刪除掉
git restore --staged xxx.java
撤銷對文件的修改
同樣也是使用 git restore xxx.java
撤銷commit
當我們想撤回一個本地的 commit 的時候、怎么辦
可以使用 git reset HEAD^ 這樣就可以成功撤銷你的 commit
head^ 等同于 head~1 表示git 倉庫的上一個版本
如果你提交了兩個 commit 都想撤回、可以使用 head~2 表示
還可以在這個命令中加上選項參數
- --mixed 不刪除工作空間改動代碼、撤銷 commit 并且撤銷 git add 操作、默認使用就是這個參數
- --soft 不刪除工作空間改動代碼、撤銷 commit、但是不撤銷 git add
- --hard 刪除工作空間改動代碼、撤銷 commit、撤銷 git add 相當于回到上一次commit狀態
https://blog.csdn.net/w958796636/article/details/53611133
git checkout
git checkout 最常見的用法莫過于對工作分支的切換了
git checkout branchName
# 該命令會將當前工作分支切換到 branchName中
也可以通過下面的命令在新分支創建的同時切換分支
git checkout -b newBranch
該命令相當于
git branch newBranch
git checkout newBranch
該命令完整語法為
git checkout -b new-branch-name copy-branch
該命令的主要關聯目標其實是.git文件夾下的HEAD文件、HEAD文件記錄了當前HEAD的信息
擴展用法
git checkout yyy.java
git checkout origin/master xxx.java
該命令主要用于檢出某一個指定文件。如果不填寫 commit id、則默認從暫存區檢出該文件、如果暫存區為空、則該文件會回滾到最近一次提交狀態
也可以指定從遠程分支中checkout某個文件
https://www.jianshu.com/p/cad4d2ec4da5
遠程倉庫的使用
查看你已經配置的遠程倉庫服務器、可以使用 git remote 命令、它會列出你指定的每一個遠程服務器的簡寫。如果你已經克隆了自己的倉庫、那么至少應該能看到origin、這是 Git 給你克隆倉庫服務器的默認名字
git remote
# 顯示對應的 url
git remote -v
添加遠程倉庫可以使用 git remote add
從遠程倉庫中抓取和拉取
- git fetch 命令只會將數據下載到你的本地倉庫--它并不會自動合并或修改你當前的工作空間、當準備好時你必須手動將其合并
- git pull 通常會從最初克隆的服務器上抓取數據并自動嘗試合并到當前所在的分支
推送到遠程分支
git push origin master
可以使用命令查看遠程倉庫的情況
git remote show orign
打標簽
Git 可以給倉庫歷史中的某個提交打上標簽、以示重視。Git 支持兩種標簽、一種是輕量級標簽、一種是附注標簽。
輕量級標簽很想一個不會改變的分支--它只是某一個特定提交的飲用
而附注標簽是存儲在 Git 參考中的一個完整對象、它是可以被檢驗的、其中包含打標簽的行嗎、電子郵件地址、日期時間、還有標簽信息。
通常會建議創建附注標簽。
- 列出標簽 git tag -l
- 創建標簽 git tag tagName / git tag -a tagName -m 'message about tag'。加上 -a 創建的是附注標簽、不加上的是一個輕量級標簽
- 展示某個標簽內容 git show tagName
- 刪除標簽 git tag -d tagName
默認情況下、git push 命令并不會傳送標簽到遠程倉庫服務器上。在創建萬標簽后你必須顯示地將標簽推送到服務器上、這個過程就行你共享遠程分支一樣。git push orign tagName
Git 分支
幾乎所有到版本系統都以某種形式支持分支、使用分支意味著你可以把你的工作從開發主線上分離出來、一面影響開發主線。在很多版本控制系統中、這是一個略微低效的過程、通常需要完成創建一個源代碼的副本。對于大項目來說、這樣的過程會耗費很多時間。
Git 處理分支的方式可謂是難以置信的輕量、創建分支這一操作幾乎能在瞬間完成、并且在不同分支之間的切換也是一樣便捷。與其他版本控制系統不同、Git 鼓勵在工作流中頻繁地使用分支與合并。
Git 保持的不是文件的變化或者差異、而是一系列不同時刻的快照。在進行提交操作時、Git 會保存一個提交對象。
在進行提交操作時、Git 會保存一個提交對象。知道了Git 保存數據的方式、我們可以自然的想到--該提交對象會包含一個只想暫存內容快照的指針,還包含作者的姓名和郵箱、提交輸入的信息以及指向它的父對象的指針。首次提交對象沒有父對象、普通提交操作產生的提交對象有一個父對象、而由多個分支合并產生的提交對象有多個父對象。
我們假設現在的工作目錄中有三個要被暫存和提交的文件。暫存操作會為每一個文件計算校驗和、然后會把當前版本的文件快照保存到暫存區中
git add README test.rb LICENSE
git commit -m 'initial commit of my project'
進行提交時、Git 會先計算每個子目錄的檢驗和、然后在 Git 倉庫中將這些檢驗和保存為樹對象。隨后 Git 會創建一個提交對象、它除了包含上面提到的信息外、還包含了指向這個樹對象的指針、如此以來、Git 就可以在需要的時候重現此次保存的快照。
現在 Git倉庫中包含五個對象、三個blob 對象(保存著文件快照)、一個樹對象(記錄著目錄結構和blob對象索引)以及一個提交對象(包含指向樹對象的指針以及所有提交信息)
做些修改后再次提交、那么這次產生的提交對象會包含一個指向上次提交對象的指針
Git 的分支、其實本質上僅僅是一個指向提交對象的可變指針。Git 的默認分支名字是 master。在多次提交操作之后、你其實已經有一個指向最后那個提交對象的 master 分支。master 分支會在每次提交時自動向前移動。
分支創建
git branch testing
Git 創建分支只是為你創建了一個可移動的新指針、它會在你當前所在的提交對象上創建一個指針
那么 Git 是如何知道當前在哪個分支上的、它使用一個名為 HEAD 的特殊指針。在 Git 中、它是一個指針、指向當前所在的本地分支。Git Branch 命令僅僅創建一個新分支、并不會自動切換到新分支中去
可以使用 git log --decorate 查看各個分支當前所指的對象
分支切換
切換到一個已存在的分支、可以使用 git checkout 命令
git checkout other-branch
這樣 HEAD 就指向了 other-branch 分支了
如果我們這個時候修改某個文件、再次 commit
testing 分支向前移動了、但是 master 分支卻沒有、它仍然指向運行 git checkout 時所指的對象。
然后我們現在切換回 master 分支
git checkout master
這個命令做了兩件事、第一件事就是使 HEAD 指回 master 分支、而是將工作目錄恢復成 master 分支所指向的快照內容。也就是說、你現在所做修改的話、項目將回到一個較舊的版本。本質上來說、這就是忽略 testing 粉做所做的修改。
這個時候我們在 master 分支上進行一次 commit
分支的新建與合并
新建分支
git checkout -b iss53
Switched to a new branch "iss53"
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
線上出現問題、需要緊急修復
git checkout master
git checkout -b hotfix
............
git commit -m 'hotfix information'
將hotfix 合并到master 分支然后緊急部署上線
$git checkout master
$git merge hotfix
Updating f42c576..3a0874c Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
在合并到時候、可以看到 “fast forward” 快進 這個詞。由于想要合并到分支 hotfix 所指向的提交 C4 是 C2 的直接后繼、因此 Git 會直接將指針向前移動。換句話說、當你試圖合并兩個分支時、如果順著一個分支走下去能夠到達另一個分支、那么 Git 合并它時、只會簡單講指針向前推進。這種情況下的合并沒有需要解決的分歧、叫做快進。
部署緊急修復到生產、然后就可以刪除 hotfix 分支了、然后切換到 iss53 中繼續工作
git branch -d hotfix
git checkout iss53
.......
git commit -m 'iss53 some commit information'
現在打算將 iss53 合并到 master 分支中、
git checkout master
git merge iss53
這和之前合并 hotfix 分支的時候不一樣、在這種情況下、iss53的開發歷史從一個更早的地方開叉出來、因為master 分支所在提交并不是 iss53 所在提交的直接祖先、Git 不得不做一些額外工作。
Git 使用兩個分支的末端所指的快照(C4 和 C5) 以及這兩個分支的公共祖先(C2)、做一個簡單的三方合并。
和之前分支指針向前推薦所不同的是、Git將此次三方合并的結果做了一個新的快照并自動創建一個新的提交指向它、這個被稱作是合并提交、它的特別之處在于它不止有一個父提交。
遇到沖突時的分支合并
有時候合并并不會那么順利。如果你在兩個不同的分支中、對同一文件的同一個部分進行了不同的修改、Git 就無法干凈的將它們合并。Git 會暫停下來、等待你解決合并產生的重提、在合并沖突的任意時刻使用 git status 命令來查看那些因合并沖突而處于未合并狀態的文件。出現沖突的文件會包含一些特殊的區段、看上去如下
這表示 HEAD 所指示的版本在這個區段的上半部分、而 iss53 分支所指示的版本在 ======= 的下半部分。為了解決沖突、你必須選擇使用 ======= 分割的兩部分中的一個、或者你可以自行合并這些內容。
<div id="footer">
please contact us at email.support@github.com </div>
上述的沖突解決方案保留了其中一個分支的修改、并將<<<<<< 和 =======和>>>>>>這些刪除掉。
在你解決了所有文件里的沖突之后、對每個文件使用 git add 命令來將其表尾沖突已解決。一旦暫存這些原本有沖突的文件、Git 就會將它們標為沖突已解決。
分支管理
git branch 命令不僅可以創建和刪除分支。如果不加任何參數運行它、則會得到當前所有分支的一個列表。
--merged 與 --no-merged 這兩個有用的選項可以過濾這個列表中已經合并或尚未合并到當前分支的分支。
拉取
當 git fetch 命令從服務器上抓取本地沒有到數據時、它并不會修改工作目錄中的內容。它只會獲取數據然后讓你合并。然后有一個命令叫做 git pull 在大多數情況下它的含義是一個 git fetch 緊接著一個 git merge命令。git pull 會查找當前所在分支所跟蹤的服務器的分支、然后從服務器抓取數據然后嘗試合并入那個遠程分支。
刪除遠程分支
git push origin --delete serverBranchName
rebase
在 Git 中整合來自不同分支的修改主要有兩種方法:merge 和 rebase。
如果使用 merge 進行整合分支
如果使用rebase 則是提取C4中引入的補丁和修改、然后在 C3 的基礎上應用一次。你可以使用rebase 命令將某個分支的所有修改都遷移到另一分支上。
在這個例子中、可以將 experiment分支 rebase 到 master 分支上
git checkout experiment
git rebase master
它的原理是首先找到這兩個分支的最近共同祖先C2、然后對比當前分支相對于祖先的歷次提交、提取相應的修改保存為臨時文件、然后將當前分支指向目標基底C3、最后將之前的臨時文件的修改依次應用。
最后將 master merge 到 experiment
要用 rebase 需要遵循這么一條準則
如果提交存在于你的倉庫之外、而別人可能基于這些提交進行開發、那么不要進行rebase
rebase 操作的實際是丟棄一些現有的提交、然后相應地新建一些內容一樣但實際上不同的提交。
總的原則就是、只對尚未推送或分享給別人的本地修改執行 rebase 操作清理歷史、從不對已推送到別處的提交執行rebase操作。
總結
以上是生活随笔為你收集整理的git克隆 不带目录_Git 系统学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 古剑奇谭网络版服务器位置,《古剑奇谭网络
- 下一篇: ios 应用和电脑共享文件夹_堪比Air