git基礎

劍指天涯心有夢發表於2018-05-23

git工作流程

 使用git就是將本地檔案(工作目錄workspace)的檔案,新增到暫存區(stage),然後提交到本地倉庫(repository),最終可以協同開發,推送到遠端倉庫(remote)

 

 

git操作一、建立Git倉庫

git版本庫,也叫做git倉庫(repository),也就是一個資料夾。

這個目錄的所有內容被git軟體管理,所有的修改,刪除,git都會跟蹤記錄,便於可以跟蹤歷史記錄,以後可以還原檔案。

兩種場景需求:

1.把已有的專案程式碼,納入git管理

cd mysite    mysite專案所在程式碼
git init        初始化git倉庫

git init命令會建立一個.git隱藏子目錄,這個目錄包含初始化git倉庫所有的核心檔案。
此步僅僅是初始化,此時專案裡的程式碼還沒有被git跟蹤,因此還需要git add對專案檔案跟蹤,然後git commit提交到本地倉庫

想知道.git檔案做了什麼事,請看git原理 >Git 內部原理 

2.新建一個專案,直接用git管理

cd 某個資料夾
git init mysite      此步會在當前路徑建立mysite資料夾,mysite資料夾中包含了.git的初始化資料夾,所有配置

那麼.git資料夾中有什麼呢?

[root@pyyuc ~/git_learning/mysite 11:08:19]#tree .git
.git
├── branches
├── config    這個專案獨有的配置
├── description
├── HEAD    head檔案指示目前被檢出的分支
├── hooks  hooks目錄包含服務端和客戶端的鉤子指令碼 hook scripts
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── index  index檔案儲存暫存區的資訊,只有git add之後才會生成,預設還沒有這個檔案
├── info    info目錄是全域性性排除檔案,用於放置不想被記錄在.gitignore檔案中的忽略模式(ignored patterns)
│   └── exclude
├── objects  儲存所有資料內容
│   ├── info
│   └── pack
└── refs  refs目錄儲存指向資料(分支)的提交物件的指標
    ├── heads
    └── tags
.git資料夾解析

3.獲取遠端倉庫程式碼

 如果你想獲取github上的程式碼,或者你公司gitlab私有倉庫的程式碼,可以使用git clone命令,下載克隆遠端倉庫的程式碼。

git clone https://github.com/django/django.git

你會發現所有的專案檔案都在這裡,等待後續開發。

git操作二、記錄更新到本地倉庫

還記得git的四個區域嗎?本地資料夾,暫存區,本地倉庫,遠端倉庫嗎?

本地資料夾未初始化,git是不認識的

本地檔案git init後,就成了git倉庫

請記住,在工作資料夾的每一個檔案,只有兩種狀態,一個是未跟蹤,一個是已跟蹤

已跟蹤的指的是已經被納入git版本管理的檔案,在git快照中有他的記錄

未跟蹤的是這個檔案既不在git快照中,也不在暫存區

git init初始化時的工作資料夾,都屬於已跟蹤了,後續的編輯操作都會標記為,已修改檔案,因此需要將修改後的檔案,加入暫存區,然後提交暫存區的檔案

 檢查檔案狀態

git status 
此命令檢視git工作目錄的檔案,處於生命週期的哪一個狀態 注意,只能在git工作目錄中輸入這個命令,他會去找.git資料夾 
第一次輸入git status會看到此狀態,沒有任何東西需要提交
[root@pyyuc ~/git_learning/mysite 12:00:34]#git status
# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)

說明當前工作目錄很乾淨,所有的已跟蹤檔案,已經被提交且未更改。
此時處在master預設分支。

git生命週期演練

請看程式碼

git init mysite                          初始化git倉庫

git status                                 檢視git狀態

echo 'print("掙了一個億")' > main.py        新建一個程式碼檔案,此時是未被git跟蹤的

git status                                檢視狀態

    On branch master

    No commits yet

    Untracked files:
      (use "git add <file>..." to include in what will be committed)

        main.py

    nothing added to commit but untracked files present (use "git add" to track)

git add main.py  開始跟蹤main.py檔案

git status   此時再看已經被跟蹤,現在已是可以被提交的狀態,此時處於暫存區

git commit -m "echo main.py" 告訴git,把暫存區的main.py提交到本地倉庫

git log     檢視剛才的commit記錄

 給檔案重新命名

我們還是在git版本庫中操作
修改main.py為mymain.py
mv main.py  mymain.py
檢視狀態
git status

直接mv的操作,會被git記錄為兩個形容,一、刪除原有檔案、二、新建了mymain.py檔案
此時新檔案還未被跟蹤,需要git add , git commit
原本的main.py還需要從暫存區刪除
[root@pyyuc
~/mysite 14:57:57]#git status # On branch 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: main.py # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # mymain.py no changes added to commit (use "git add" and/or "git commit -a")

git rm main.py  刪除暫存區的main.py

git commit -m "mv mymain.py"  提交新的mymain.py

這樣的步驟很麻煩,可以直接git mv 命令即可

剛才的mv記錄,可以通過git log檢視歷史記錄,已經提交的id

可以通過git reset 回退歷史版本,回退到改名之前

[root@pyyuc ~/mysite 15:10:12]#git log
commit f60fa7f1312843aa57edc9464192c9d891f23fb5
Author: pyyu <yc_uuu@163.com>
Date:   Sat Dec 22 15:08:02 2018 +0800

    mv mymain.py

commit 65e0a2239909fd5aabc5928ec4431de3f163a195
Author: pyyu <yc_uuu@163.com>
Date:   Sat Dec 22 14:51:07 2018 +0800

    echo main.py


回退到上一次commit版本,(注意這個命令,很危險,慎用)
git reset --hard 65e0a2239909fd5aabc5928ec4431de3f163a195 
--hard 清空暫存區和工作目錄資料

改名最正確的姿勢

git mv main.py mymain.py  

git commit -m "mv mymain.py"

檢視git版本歷史

在我們使用git的時候,會對程式碼檔案不停的修改,不斷的提交到程式碼倉庫。

這個就如同我們打遊戲時候,儲存關卡記錄的操作。

在打boss之前,先做一個存檔,防止你這個渣渣,被boss一招秒殺,又得從頭再來。。。。。

因此被boss弄死,可以從存檔,重新開始遊戲。。。。

Git也是一樣

當你的程式碼寫好了一部分功能,就可以儲存一個"存檔",這個存檔操作就是git commit,如果程式碼出錯,可以隨時回到"存檔"記錄

檢視"存檔"記錄,檢視commit提交記錄的命令 git log

git log命令顯示,從最新的commit記錄到最遠的記錄順序。

git log --oneline    一行顯示git記錄
git log --oneline  --all  一行顯示所有分支git記錄
git log --oneline --all -4 --graph 顯示所有分支的版本演進的最近4條
git log -4  顯示最近4條記錄
git log --all     顯示所有分支的commit資訊




git branch -v 檢視分支資訊
git help --web log 以web介面顯示log的引數

git版本回退,回到過去

git log可以檢視歷史版本記錄
git reset --hard命令可以回退版本
git reset --hard HEAD^ 回退到上個版本
HEAD表示當前版版本
HEAD^表示上個版本
HEAD^^上上個版本

也可以直接git reset --hard 版本id號

 

 

 

git穿梭未來

當你發現你git reset --hard回退錯了。。。怎麼辦?別怕git reflog 記錄了你每一次命令

git reflog
80f9496 HEAD@{1}: reset: moving to HEAD^
b7a8740 (HEAD -> master) HEAD@{2}: commit: echo 123
80f9496 HEAD@{3}: commit: echo my.txt
bf5879e HEAD@{4}: commit (initial): echo my.txt

我想回到某一個點,可以再次git reset --hard 版本id

git工作區

在我們進行git init mygit初始化一個git專案時,這個mygit資料夾,就是一個工作區(working Directory)

yudanL-2:mygit root# pwd
/data/mygit
yudanL-2:mygit root# ls
.git    my.txt

git倉庫

工作區裡有一個.git隱藏資料夾,就是git的本地倉庫

.git資料夾裡有一個index檔案,就是git的暫存區,也叫做stage

.git資料夾裡的HEAD檔案就是git的一個指標

原理圖

 

git記錄的是工作區的修改記錄

撤銷修改記錄,只能在未提交到暫存區之前 

git status
git checkout -- my.txt 放棄工作區的修改操作

如果你修改了檔案,還新增到了暫存區 git add,那麼只能撤銷暫存區的操作,再撤銷修改記錄

git status    
git reset HEAD readme.txt  撤銷暫存區的修改,unstage操作
git checkout -- readme.txt

git刪除檔案與恢復檔案

如果你直接在工作區刪除檔案,動作會被git記錄
rm -rf my.txt    刪除了工作區的檔案,git倉庫還有記錄
git status    檢視狀態,可以檢測到my.txt被刪除

如果確認檔案無用,可以commit到git倉庫
git rm "my.txt"
git commit -m "remove my.txt"

如果你想恢復檔案,可以通過git倉庫的程式碼,替換工作區的程式碼

rm -rf my.txt
git checkout -- my.txt

git stash

儲存當前暫存區和工作區的改動儲存起來,執行完畢git stash之後,再次執行git status就會發現當前已是個乾淨的工作區,通過git stash list檢視結果

命令整理

git stash 儲存暫存區,工作區進度

git stash list 檢視stash儲存的列表以及id

git stash pop  恢復最新的stash進度到工作區

git stash pop stash_id  恢復指定的stash進度

git stash clear 清空所有儲存的stash進度

git stash drop stash_id  刪除一個儲存的stash進度

git stash apply 恢復stash儲存,且不刪除stash list中的記錄

git stash實際用法

git stash會把所有未提交的修改(包括暫存的和非暫存的)都儲存起來,用於後續恢復當前工作目錄。
比如下面的中間狀態,通過git stash命令推送一個新的儲藏,當前的工作目錄就乾淨了。

[root@yugo mydjango]# ls
manage.py  mydjango
#比如我臨時想新建一個app01,進行開發,但是突然開發到一半,線上程式碼出bug了,我得立即去修復,我希望能臨時儲存一下,我目前的修改操作,bug完畢了,再找回來繼續開發
[root@yugo mydjango]# django-admin startapp app01
[root@yugo mydjango]#
[root@yugo mydjango]#
[root@yugo mydjango]# git add .
[root@yugo mydjango]# git status # On branch master # Changes to be committed: # (use
"git reset HEAD <file>..." to unstage) # # new file: app01/__init__.py # new file: app01/admin.py # new file: app01/apps.py # new file: app01/migrations/__init__.py # new file: app01/models.py # new file: app01/tests.py # new file: app01/views.py # [root@yugo mydjango]# [root@yugo mydjango]# [root@yugo mydjango]# git stash Saved working directory and index state WIP on master: b16ccc0 v1 mydjango HEAD is now at b16ccc0 v1 mydjango
#此時app01被放入暫存區,看不到了 [root@yugo mydjango]# ls manage.py mydjango

#這裡應該使用 git stash save 儲存名
git stash save "my app01 stash"

找回stash

[root@yugo mydjango]# ls
manage.py  mydjango
[root@yugo mydjango]# git stash pop # On branch master # Changes to be committed: # (use
"git reset HEAD <file>..." to unstage) # # new file: app01/__init__.py # new file: app01/admin.py # new file: app01/apps.py # new file: app01/migrations/__init__.py # new file: app01/models.py # new file: app01/tests.py # new file: app01/views.py # Dropped refs/stash@{0} (5758c689354a34a168063a5bfa5d4bb3ca291f3b)
[root@yugo mydjango]# ls app01 manage.py mydjango

檢視stash列表

[root@yugo mydjango]# git stash list
stash@{0}: WIP on master: b16ccc0 v1 mydjango

移除stash

預設刪除第一個stash
[root@yugo mydjango]# git stash drop
Dropped refs/stash@{0} (8af1c158977d5fe8bd398561ad8777514f8d22d1)

 

相關文章