目錄git
Markdown版本筆記 | 個人GitHub首頁 | 個人博客 | 個人微信 | 個人郵箱 |
---|---|---|---|---|
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
cd
:change directory 改變目錄,bash中不帶參數時默認進入【/c/Users/當前用戶】目錄,cmd中不帶參數時等價於pwdcd -
:回到前一個目錄,cmd中沒有此命令cd ..
:回到父目錄cd aaa
:進入指定目錄,能夠是相對目錄或絕對目錄pwd
:打印工做目錄路徑ls
和ll
:列出當前目錄中的全部文件,cmd中沒有ll命令touch aaa.txt
:在當前目錄下新建一個文件mkdir aaa
:在當前目錄下新建一個目錄rm aaa.txt
:刪除指定的文件rm -r aaa
:刪除指定的目錄,參數r
爲recusive是遞歸的意思mv aaa.txt bbb
:將文件移到指定目錄下q
:結束一個命令Ctrl + Insert
Shift + Insert
Alt + F3
,按Enter
或Shift + Enter
選中下/上一個匹配內容Ctrl + 【+/-】
Alt + F8
(重置),cmd 下的命令是 cls
【重要】Alt + F11
,再按一次還原左/右
移動光標:Alt + B/F
【重要】起始/結束
位置:Ctrl + A/E
【重要】左/右
移動光標:Ctrl + B/F
左/右
側的全部內容:Ctrl + U/K
【重要】左
側的單詞:Ctrl + W
【重要】右
側的單詞:Alt + D
左/右
側的字符:Ctrl + H/D
(或backspace鍵、delete鍵)Git默認的編輯器是Vim,在不少情境下會遇到它,例如commit提交,若是提供-m
指令,直接在後面寫上這次提交的說明信息;若是不提供-m
指令,默認將會彈出Vim編輯器,以下:github
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit.
此編輯器和平時所用編輯器差距很大,Vim編輯器命令不少,下面介紹一下簡單操做,以完成基本的Git操做。shell
Vim主要有以下兩種模式:vim
ESC
或 Ctrl + [
進入,此模式下沒法輸入內容,可是能夠複製、黏貼、保存、退出
:w
表示保存:q
表示離開,若是未保存會有提示:q!
表示不保存離開:wq
表示保存並離開(用的最多)基本步驟:bash
git rebase -i HEAD~影響的最少commit數
或git rebase -i 前一個commitId
須要合併的那條commit
前面的pick
改成s
,保存後退出如下是詳細操做微信
在使用 Git 做爲版本控制的時候,咱們可能會因爲各類各樣的緣由提交了許多臨時的 commit
,而這些 commit 拼接起來纔是完整的任務。那麼咱們爲了不太多的 commit 而形成版本控制的混亂,一般咱們推薦將這些 commit 合併成一個。app
首先你要知道本身想合併的是哪幾個提交,可使用 git log 命令來查看提交歷史,假如最近 4 條歷史以下:編輯器
commit 8b5cbda494a68582164048159e605e731f357444 (HEAD -> master) commit a472755058e78a33595390f87d03d855fc25da84 commit 6ab13045d47157842961fae70baa7ef25e1856b1 commit 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f (origin/master, origin/HEAD)
歷史記錄是按照時間排序的,時間近的排在前面。gradle
若是想要合併第 2 和第 3 條記錄,有兩個方法,這兩個方法效果是一致的:優化
git rebase -i HEAD~3
以前
的版本號git rebase -i 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f
請注意 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f 這個版本是不參與合併的,能夠把它當作一個座標
執行了 rebase 命令以後,會彈出一個窗口,內容以下:
pick 6ab1304 11111111 pick a472755 222222222 pick 8b5cbda 3333333 # Rebase 00b8fe5..8b5cbda onto 00b8fe5 (3 commands) # # Commands: # p, pick = use commit # r, reword(改寫) = use commit, but edit the commit message # e, edit = use commit, but stop for amending(修正) # s, squash(塞入) = use commit, but meld into(融入) previous commit # f, fixup(修正) = like "squash", but discard(丟棄) this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out(被註釋掉的)
能夠看到,裏面有詳細的命令提示。咱們將須要合併的那條commit
前面的pick
改成s
,以後保存並關閉文本編輯窗口便可。改完以後文本內容以下:
pick 6ab1304 11111111 s a472755 222222222 pick 8b5cbda 3333333
而後保存退出。若是沒有衝突,或者衝突已經解決,則會出現以下的編輯窗口:
# This is a combination of 2 commits. # This is the 1st commit message: 11111111 # This is the commit message #2: 222222222 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit(空消息會終止提交). # # Date: Sun Jul 7 21:14:02 2019 +0800 # # interactive(互動) rebase in progress; onto 00b8fe5 # Last commands done (2 commands done): # pick 6ab1304 11111111 # squash a472755 222222222 # Next command to do (1 remaining command): # pick 8b5cbda 3333333 # You are currently rebasing branch 'master' on '00b8fe5'. # # Changes to be committed: # modified: build.gradle
若是不作任何修改的話,默認是保留兩次 commit 的日誌,中間有一個空白行,你能夠隨意修改合併後的日誌。
保存並退出後再次輸入 git log 查看 commit 歷史信息,你會發現這兩個 commit 已經合併了。
commit 9adb987d31f11f8d38f8d817096d2d21a7390a1d (HEAD -> master) commit 052ea3ea0b30c375e79ad9e891c5e5202768b11b commit 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f (origin/master, origin/HEAD)
雖然咱們只是合併了第 2 條和第 3 條的commit,可是第 1 條的 commitId 也變了。
若是有衝突,須要修改。修改的時候要注意,保留最新的歷史,否則咱們的修改就丟棄了。
修改之後要記得敲下面的命令:
git add . git rebase --continue
若是你想放棄此次壓縮的話,執行如下命令:
git rebase --abort
和上面的操做基本一致。
例如個人提交歷史以下:
commit 831be8ec644c4943374adca03880732c7ec9d6bd (HEAD -> master) commit 6a8ecb529a4ec6b6e0fc83e0789043b7785e73fe commit 3b228d8af9e52806c106ef3f0c27e622b5407faf commit 9adb987d31f11f8d38f8d817096d2d21a7390a1d (origin/master, origin/HEAD)
我想刪除第2條和第3條提交,基本步驟:
git rebase -i HEAD~影響的最少commit數
或git rebase -i 前一個commitId
須要刪除的那幾條commit
前面的pick
改成d
,保存後退出注意,這個操做感受出現衝突的機率比較大,例如我上面三次commit都是在同一個文件的第一行插入一行新的文字:
//添加3 //添加2 //添加1
執行rebase後就會提示衝突了:
git rebase -i 9adb987d31f11f8d38f8d817096d2d21a7390a1d Auto-merging build.gradle CONFLICT (content): Merge conflict in build.gradle error: could not apply 831be8e... 333 Resolve all conflicts manually手動, mark them as resolved with "git add/rm <conflicted_files>", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply 831be8e... 333
解決衝突後按如下操做:
git add . git rebase --continue
能夠發現,相應 commit 都還原了,包括修改的文件以及提交的commit記錄。
和上面的操做基本一致。
例如個人提交歷史以下:
commit 442... (HEAD -> master) commit 5a1... commit 305... commit f30... (origin/master, origin/HEAD)
我想修改第2條和第3條提交,基本步驟:
git rebase -i HEAD~影響的最少commit數
或git rebase -i 前一個commitId
須要修改的那幾條commit
前面的pick
改成r
,保存後退出注意,修改後會生成新的commitId
cherry-pick 的翻譯是擇優挑選
,使用git cherry-pick
命令,能夠選擇將現有的一個或者多個提交的修改引入當前內容。
git cherry-pick <commitid> <commitid>
挑選多個提交合並,提交之間用空格
相隔。
git cherry-pick <start-commit>..<end-commit>
挑選一個範圍內的多個提交合並,不包含start-commit(最先的提交),包含end-commit(最近的提交)。另外要注意兩個 commit 之間要求有連續關係的,而且前者要在後者以前,順序不能顛倒。
git cherry-pick <start-commit>^..<end-commit>
這個和上面同樣,區別就是加了一個^
符號,就變成閉區間了,包含 start-commit。
git cherry-pick <branch name>
挑選 branch 最頂端的提交。
git cherry-pick --continue //繼續下個操做 git cherry-pick --quit //退出 git cherry-pick --abort //中止本次操做
當 cherry-pick 多個 commit 時,假設遇到衝突:
--continue
繼續進行下個--quit
結束 cherry-pick 操做可是不會影響衝突以前多個提交中已經成功的--abort
直接打回原形,回到 cherry-pick 前的狀態,包括多個提交中已經成功的參考:git branch -d 和 git branch -D 的區別
結論:
在使用-d
刪除分支時,該分支必須徹底和它的上游分支merge完成,若是沒有上游分支,必需要和HEAD
徹底merge。
出現的案例一
git branch -d v0.1 error: The branch 'v0.1' is not fully merged. If you are sure you want to delete it, run 'git branch -D v0.1'.
三、而後切到 v0.1 上,將修改推送到遠端:git push origin v0.1
四、而後再切到其餘分支後刪除 v0.1 試試,能夠發現刪除成功,可是有警告
git branch -d v0.1 warning: deleting branch 'v0.1' that has been merged to 'refs/remotes/origin/v0.1', but not yet merged to HEAD. Deleted branch v0.1 (was 4a79623).
上面的步驟進行一些優化:
四、假如咱們後面刪除前是切到了 master 分支,因此當前HEAD
爲 master 分支("因此"這個詞用的對嗎?)
五、將 v0.1 上的修改 merge 過來git merge v0.1
,而後再刪除 v0.1 試試,能夠發現刪除成功且沒有警告
出現的案例二
git branch v0.1_copy
(此分支並無上游分支)git branch -d v0.1_copy error: The branch 'v0.1_copy' is not fully merged. If you are sure you want to delete it, run 'git branch -D v0.1_copy'.
五、而後切到 v0.1 上,並將 v0.1_copy 上的修改 merge 過來git merge v0.1_copy
六、而後再刪除 v0.1_copy 試試,能夠發現刪除成功且沒有警告
git branch -d v0.1_copy Deleted branch v0.1_copy (was 03cb1c6).
總結
簡單來講就是這麼一個設計思想:
HEAD
徹底merge才能刪除總之一句話,刪除分支不能致使有任何已作的 commit 沒法追蹤,若是你想這麼作,必須使用 -D 達到你的目的
一、如今有一個本地分支 v0.1,且其和遠端分支 v0.1 關聯,此時你在本地 v0.1 作的任何修改均可以經過git push origin v0.1
推到遠端,這很正常
二、而後你經過git branch v0.1_backup
建立了一個備份分支,而後 checkout 到此分支後作了一些修改,當你 commit 後 push 到遠端的 v0.1 時問題就出現了
git push origin v0.1 Everything up-to-date
其實這裏的 "Everything up-to-date(最新)", 的含義是:
"all the branches you've told me how to push are up to date".
也就是說遠端的v0.1是最新的
而且此時其實並無push到遠端的
git status On branch v0.1_backup Your branch is ahead of 'origin/v0.1' by 1 commit.
緣由是很簡單的,分支 v0.1_backup 並無和遠端分支關聯
$ git branch -vv master de18ed6 [origin/master] 修改1 v0.1 03cb1c6 [origin/v0.1] 修改2 * v0.1_backup 88eb433 修改3
三、如今你經過git branch -u origin/v0.1 v0.1_backup
能夠將其和遠端的 v0.1 關聯
$ git branch -vv master de18ed6 [origin/master] 修改1 v0.1 03cb1c6 [origin/v0.1] 修改2 * v0.1_backup 88eb433 [origin/v0.1: ahead 1] 修改3
四、而後再 push 到遠端的 v0.1 會發現,問題依舊
解決方式有三個
一、更名,將本地分支名 v0.1_backup 改成和遠程分支名同樣的 v0.1 就能夠了。神馬,同名的分支已存在?那你爲何不在已存在的那個分支上操做呢?
二、merge,好比上面說的和遠程分支同名的本地分支 v0.1 已存在時,能夠先將 v0.1_backup 的修改 merge 到 v0.1 上,而後再在 v0.1 上 push 就能夠了。雖然麻煩,可是這是標準操做(我的感受)。
三、使用下面的命令也能夠
git push origin v0.1_backup:v0.1
2019-7-14