1-5關 12.16c++
6-11關 12.17git
本文章僅記錄githug過關經歷。
詳細介紹及安裝方法不在本文章範圍以內,請自行解決。github
本文首發於Cmd-Markdown,此處僅爲md內容粘貼。
如如有顯示不全,圖片缺失,亂碼或排版問題請訪問原發布地址。vim
目前爲止,githug大部分問題查閱git book便可解決。ruby
Name: init Level: 1 Difficulty: * A new directory, `git_hug`, has been created; initialize an empty repository in it.
參見gitbook-2.1ide
若是你打算使用 Git 來對現有的項目進行管理,你只須要進入該項目目錄並輸入:學習
$ git init
測試
該命令將建立一個名爲 .git 的子目錄,這個子目錄含有你初始化的 Git 倉庫中全部的必須文件,這些文件是 Git 倉庫的骨幹。ui
即爲初始化一個空的倉庫,git init
便可。this
Name: config Level: 2 Difficulty: * Set up your git name and email, this is important so that your commits can be identified.
設置用戶名和email。用來標識主機。
使用githug hint 並查閱git book可知,
git book- 1.6
當安裝完 Git 應該作的第一件事就是設置你的用戶名稱與郵件地址。 這樣作很重要,由於每個 Git 的提交都會使用這些信息,而且它會寫入到你的每一次提交中,不可更改:
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
再次強調,若是使用了 --global 選項,那麼該命令只須要運行一次,由於以後不管你在該系統上作任何事情, Git 都會使用那些信息。 當你想針對特定項目使用不一樣的用戶名稱與郵件地址時,能夠在那個項目目錄下運行沒有 --global 選項的命令來配置。
Name: add Level: 3 Difficulty: * There is a file in your folder called `README`, you should add it to your staging area Note: You start each level with a new repo. Don't look for files from the previous one.
staging area是什麼?
add 是什麼操做?
學習完2.2天然能夠明白這個題要求作什麼,也能夠回答這兩個問題了。
staging area即爲暫存區,add命令能夠將未跟蹤的文件添加到暫存區。
addgit add
能夠經過參數控制,從而將指定文件添加到git控制中。
$ git add README $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README
關於git add
的更多信息
> 這是個多功能命令:能夠用它開始跟蹤新文件,或者把已跟蹤的文件放到暫存區,還能用於合併時把有衝突的文件標記爲已解決狀態等。 將這個命令理解爲「添加內容到下一次提交中」而不是「將一個文件添加到項目中」要更加合適
git系統中文件的全部狀態
其次,從使用者的角度描述大體一下git系統中文件的全部狀態首先對文件作出修改,在修改以前,文件天然處於未修改(unmodified)狀態, 修改以後,天然處於已修改(modified)狀態,這很好理解。而後將作出的改動提交(commit)到git,確認作出修改,提交歷史記錄中就多了一條。同時文件又返回未修改(unmodified)狀態,也能夠叫作,已提交狀態
大體意思以下
版本 | 用戶 | 說明 | 日期 |
---|---|---|---|
1 | 張三 | 刪除了軟件服務條款5 | 7/12 10:38 |
2 | 張三 | 增長了License人數限制 | 7/12 18:09 |
3 | 李四 | 財務部門調整了合同金額 | 7/13 9:51 |
4 | 張三 | 延長了免費升級週期 | 7/14 15:17 |
不過只有2種狀態是否方便呢?是否能知足全部需求呢?
新添加的文件,應該處於什麼狀態呢?不該該是已提交,由於尚未提交過,可是已修改也不太對,尚未對文件作出修改呢
若是我今天進行了一些修改,可是一部份內容屬於測試內容,不但願提交該怎麼辦?
在cs領域有句名言
「計算機科學領域的任何問題均可以經過增長一個間接的中間層來解決」
「Any problem in computer science can be solved by anther layer of indirection.」
是時候學習文件的第三種狀態了,暫存(staged),或者叫待提交。
這首先能夠解決第一個問題,新加入git系統的文件應該處於暫存,這樣就能夠直接在下一次進行提交了,同時,這也符合git add命令的功能
其次,多了暫存這樣一箇中間狀態,咱們就能夠按照本身的需求將已經修改的文件添加到暫存區,
好比我修改了10個文件,但我只將其中的2個添加到暫存區(Changes to be committed)或者說待提交區。這樣,下一次提交的時候,就只會將這兩個文件進行提交。其他文件仍舊只是已修改。
如今這三個狀態之間的關係是這樣的:
A[未修改/已提交 ] -->|修改| B(已修改) B --> |暫存/add|C[暫存區/待提交] C --> |提交/commit|A
固然,若是隻修改了一個文件,卻打算提交,也能夠跳過暫存區,直接提交。git commit -a
本節全部命令小結
$ git add $ git commit [-a]
Name: commit Level: 4 Difficulty: * The `README` file has been added to your staging area, now commit it.
通過上述的2.2大體學習,這一關就十分簡單了,提交(commit)這個readme便可。
-> % git commit [master (根提交) b08b86e] this just is a test 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README
Name: clone Level: 5 Difficulty: * Clone the repository at https://github.com/Gazler/cloneme.
參見 gitbook-2.1(其實clone應該和init放在一塊兒的)
克隆倉庫的命令格式是 git clone [url] 。 好比,要克隆 Git 的可連接庫 libgit2,能夠用下面的命令:
$ git clone https://github.com/libgit2/libgit2
這會在當前目錄下建立一個名爲 「libgit2」 的目錄,並在這個目錄下初始化一個 .git 文件夾,從遠程倉庫拉取下全部數據放入 .git 文件夾,而後從中讀取最新版本的文件的拷貝。 若是你進入到這個新建的 libgit2 文件夾,你會發現全部的項目文件已經在裏面了,準備就緒等待後續的開發和使用。 若是你想在克隆遠程倉庫的時候,自定義本地倉庫的名字,你可使用以下命令:
$ git clone https://github.com/libgit2/libgit2 mylibgit
這將執行與上一個命令相同的操做,不過在本地建立的倉庫名字變爲 mylibgit。
按照gitbook進行操做便可克隆一個已有倉庫。
-> % git clone https://github.com/Gazler/cloneme 正克隆到 'cloneme'... remote: Counting objects: 7, done. remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 7 Unpacking objects: 100% (7/7), done. 檢查鏈接... 完成。
Name: clone_to_folder Level: 6 Difficulty: * Clone the repository at https://github.com/Gazler/cloneme to `my_cloned_repo`.
即爲第5關中介紹的內容,克隆一個倉庫到指定文件夾。
-> % git clone https://github.com/Gazler/cloneme my_cloned_repo 正克隆到 'my_cloned_repo'... remote: Counting objects: 7, done. remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 7 Unpacking objects: 100% (7/7), done. 檢查鏈接... 完成。
Name: ignore Level: 7 Difficulty: ** The text editor 'vim' creates files ending in `.swp` (swap files) for all files that are currently open. We don't want them creeping into the repository. Make this repository ignore `.swp` files.
vim 會爲正在編輯的文件生成.swp
文件,對這類臨時文件進行版本控制是無心義的,也不須要顯示出來。因此請忽視以.swp
結尾的文件。
通常咱們總會有些文件無需歸入 Git 的管理,也不但願它們總出如今未跟蹤文件列表。 一般都是些自動生成的文件,好比日誌文件,或者編譯過程當中建立的臨時文件等。 在這種狀況下,咱們能夠建立一個名爲 .gitignore 的文件,列出要忽略的文件模式。
如下是一些規範和詳細的例子
全部空行或者以 # 開頭的行都會被 Git 忽略。
可使用標準的 glob 模式匹配。
匹配模式能夠以(/)開頭防止遞歸。
匹配模式能夠以(/)結尾指定目錄。
要忽略指定模式之外的文件或目錄,能夠在模式前加上驚歎號(!)取反。
glob模式解釋
星號(
*
)匹配零個或多個任意字符;[abc] 匹配任何一個列在方括號中的字符(這個例子要麼匹配一個 a,要麼匹配一個 b,要麼匹配一個 c);
問號(?)只匹配一個任意字符;
若是在方括號中使用短劃線分隔兩個字符,表示全部在這兩個字符範圍內的均可以匹配(好比 [0-9] 表示匹配全部 0 到 9 的數字)。
使用兩個星號(
*
) 表示匹配任意中間目錄,好比a/**/z 能夠匹配 a/z, a/b/z 或 a/b/c/z等。
一些例子
# no .a files *.a # but do track lib.a, even though you're ignoring .a files above !lib.a # only ignore the TODO file in the current directory, not subdir/TODO /TODO # ignore all files in the build/ directory build/ # ignore doc/notes.txt, but not doc/server/arch.txt doc/*.txt # ignore all .pdf files in the doc/ directory doc/**/*.pdf
因此按照要求忽略.swp
便可。使用 *.swp
便可匹配。
-> % cat .gitignore .profile.yml .gitignore *.swp
Name: include Level: 8 Difficulty: ** Notice a few files with the '.a' extension. We want git to ignore all but the 'lib.a' file.
忽視全部.a
文件,除了lib.a
。
根據第七關在2.2所學的內容便可寫出匹配模式。*.a
即會匹配全部.a
文件,接下來須要不匹配lib.a
文件。
採用!
便可,也就是!lib.a
。
-> % cat .gitignore .profile.yml .gitignore *.a !lib.a
Name: status Level: 9 Difficulty: * There are some files in this repository, one of the files is untracked, which file is it?
一個新初始化的倉庫內,全部文件都是未跟蹤的(untracked)。即爲沒有歸入git。
顯而易見,不是全部的文件都須要歸入版本控制,好比c或者c++的.o
文件,或者其餘語言的中間生成文件,以及一些配置文件,與項目內容沒有直接關係,並且能夠生成,徹底不須要歸入版本控制。git status
能夠查看當前全部文件的狀態, untracked即爲未跟蹤
Untracked files: (use "git add <file>..." to include in what will be committed) README
使用git status便可輕易解決此問題,database.yml未跟蹤
-> % git status 位於分支 master 初始提交 要提交的變動: (使用 "git rm --cached <文件>..." 以取消暫存) 新文件: Guardfile 新文件: README 新文件: config.rb 新文件: deploy.rb 新文件: setup.rb 未跟蹤的文件: (使用 "git add <文件>..." 以包含要提交的內容) database.yml
Name: number_of_files_committed Level: 10 Difficulty: * There are some files in this repository, how many of the files will be committed?
這個倉庫裏有數個文件,那麼將要提交的文件有多少個?
要提交的文件,也就是暫存區的文件,新添加的文件會在暫存區內,修改過並add的文件也在暫存區內。
使用git status便可獲知有多少個文件待提交。
-> % git status 位於分支 master 要提交的變動: (使用 "git reset HEAD <文件>..." 以取消暫存) 新文件: rubyfile1.rb 修改: rubyfile4.rb 還沒有暫存以備提交的變動: (使用 "git add <文件>..." 更新要提交的內容) (使用 "git checkout -- <文件>..." 丟棄工做區的改動) 修改: rubyfile5.rb 未跟蹤的文件: (使用 "git add <文件>..." 以包含要提交的內容) rubyfile6.rb rubyfile7.rb
Name: rm Level: 11 Difficulty: ** A file has been removed from the working tree, however the file was not removed from the repository. Find out what this file was and remove it.
一個文件已經從工做目錄中刪除了,可是它卻沒有從git倉庫中刪除,請找出這個文件,並刪除它。
git倉庫中存儲的是什麼呢?爲何文件刪除了,卻沒有從git系統中刪除?
先使用git status
看看狀況吧
-> % git status 位於分支 master 還沒有暫存以備提交的變動: (使用 "git add/rm <文件>..." 更新要提交的內容) (使用 "git checkout -- <文件>..." 丟棄工做區的改動) 刪除: deleteme.rb 修改還沒有加入提交(使用 "git add" 和/或 "git commit -a")
查看得知,確實有一個文件被刪除了,可是卻能夠在git中看到
那麼問題來了,如何將一個文件從git中刪除呢?
要從 Git 中移除某個文件,就必需要從已跟蹤文件清單中移除(確切地說,是從暫存區域移除),而後提交。 能夠用 git rm 命令完成此項工做,並連帶從工做目錄中刪除指定的文件,這樣之後就不會出如今未跟蹤文件清單中了。
若是隻是簡單地從工做目錄中手工刪除文件,運行 git status 時就會在 「Changes not staged for commit」 部分(也就是 未暫存清單)看到:
$ rm PROJECTS.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: PROJECTS.md no changes added to commit (use "git add" and/or "git commit -a")
而後再運行 git rm 記錄這次移除文件的操做:
$ git rm PROJECTS.md rm 'PROJECTS.md' $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: PROJECTS.md
下一次提交時,該文件就再也不歸入版本管理了。
按照上述內容操做便可。
-> % git rm deleteme.rb rm 'deleteme.rb' -> % git status 位於分支 master 要提交的變動: (使用 "git reset HEAD <文件>..." 以取消暫存) 刪除: deleteme.rb