身为技术人员,都知道Git是干嘛的。从服务端角度它是代码仓库,可以多人协作、版本控制、高效处理大型或小型项目所有内容;从客户端讲,它能够方便管理本地分支、且与服务端代码的同步,从拉取、合并、提交等等管理分支都靠它!
Git轻量、易于学习,如果不用搭建和维护代码仓库的话(运维职责),只要掌握几个git常用命令即可在工作中轻松应对。
下面简单介绍几个概念,同时列出工作中常用命令:
主要概念
快速入门,弄明白以下几个概念即可:
-
工作区(Working Directory):就是你在电脑里能看到的目录,或克隆(clone)下来的目录;
-
版本库(Repository):工作区里面有一个隐藏目录.git,这个不是工作区,而是Git的版本库;
-
暂存区(stage):版本库中有一个叫stage的暂存区,git add可以把要提交的内容放到暂存区;
-
主分支(master):版本库还有一个叫master的主分支,git commit把暂存区所有内容提交到当前分支;
主要用法
工作中,一般我们提交代码只要四步:
-
第一步,git pull 拉取代码,提交代码前确保和服务端仓库一致,避免冲突;
-
第二步,git add ./your_file.txt 把文件添加进去,实际就是从工作区提交到暂存区;
-
第三步,git commit -m 'first commit'提交更改,再把暂存区所有内容提交到当前分支(默认master);
-
第四步,git push [remoteName]推送到远程仓库,也就是推到服务端,这样别人就能拉取pull你的代码;
常见用法
平时工作也就用到上面四个步骤,当然了凡事有例外,下面说几个例外的处理办法:
一、checkout切换分支
git checkout <branch>:切换到你需要的分支(dev、hotfix)
git checkout -b <branch>:如果没有分支,加上-b参数表示创建并切换;
参考链接:https://git-scm.com/docs/git-checkout
二、git提交后撤销问题
撤销得分三种情况:
-
第一,已经修改文件但未执行git add的撤销方法;
我故意在.gitignore文件修改之后且没有git add,直接通过git checkout -- <file>撤销;
但是此命令不会撤销新建的文件,因为新建文件还没加入到Git管理系统中,
所以git是未知的,自己手动删除就好了。
λ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
D:\learning\git\work (master -> origin)
λ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .gitignore
no changes added to commit (use "git add" and/or "git commit -a")
D:\learning\git\work (master -> origin)
λ git checkout -- .gitignore
D:\learning\git\work (master -> origin)
λ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
扩展:
命令git checkout -- .gitignore意思就是,把.gitignore文件在工作区的修改全部撤销,这里有两种情况:
一种是.gitignore自修改后还没有被放到暂存区,现在撤销修改就回到和版本库一模一样的状态;
一种是.gitignore已经添加到暂存区,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
参考链接:https://www.liaoxuefeng.com/wiki/896043488029600/897889638509536
-
第二,已经修改文件且git add的撤销方法
需要先执行git reset .gitignore撤销到未git add状态,再执行第一步即可。
λ git add .gitignore
D:\learning\git\work (master -> origin)
λ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: .gitignore
D:\learning\git\work (master -> origin)
λ git reset .gitignore
Unstaged changes after reset:
M .gitignore
D:\learning\git\work (master -> origin)
λ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .gitignore
no changes added to commit (use "git add" and/or "git commit -a")
D:\learning\git\work (master -> origin)
λ git checkout -- .gitignore
D:\learning\git\work (master -> origin)
λ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
-
第三,Git已经commit如何撤销:
通过git reset --hard commitid直接回到未修改状态。
λ git add .gitignore
λ git commit -m "test"
#(省略无用部分)
λ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
D:\learning\git\work (master -> origin)
λ git log
commit b7de9378f39834dbc8304d4a8d30f39a4003c673 (HEAD -> master)
Author: test <test@163.com>
Date: Mon Sep 14 02:59:02 2020 +0800
test
commit b3ed1078e543cdb26b984dac584df9db7553d506 (origin/master, origin/HEAD)
Author: test <test@163.com>
Date: Mon Sep 14 02:39:54 2020 +0800
09142020
D:\learning\git\work (master -> origin)
λ git reset --hard b3ed1078e543cdb26b984dac584df9db7553d506
HEAD is now at b3ed107 09142020
D:\learning\git\work (master -> origin)
λ git log
commit b3ed1078e543cdb26b984dac584df9db7553d506 (HEAD -> master, origin/master, origin/HEAD)
Author: test <test@163.com>
Date: Mon Sep 14 02:39:54 2020 +0800
09142020
D:\learning\git\work (master -> origin)
λ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
三、git stash保存和恢复工作区内容
git stash可以将你已经修改,但不想提交(git push)的代码临时保存到堆栈中,也就是回归到你git pull时的状态。然后就能随意切换分支救火,完成后切换回来再git push pop即可恢复之前的修改内容。stash不仅可以恢复到原先开发的分支,也可以恢复到其他任意指定的分支上(可跨分支)。
-
git stash
保存当前工作进度,会把暂存区和工作区的改动保存起来。
执行完之后再git status,会发现当前是一个干净的工作区,没有任何改动。
使用git stash save 'message...'可以添加一些注释
-
git stash list
显示保存进度的列表。也就意味着,git stash命令可以多次执行。 -
git stash pop
恢复最新的进度到工作区。git默认会把工作区和暂存区的改动都恢复到工作区。 -
git stash pop stash@{stash_id}
恢复指定的进度到工作区。stash_id通过git stash list命令得到的
通过git stash pop命令恢复进度后,会删除当前进度。 -
git stash drop stash@{stash_id}
可以使用git stash drop命令,后面可以跟stash_id
或使用git stash clear命令,删除所有缓存的stash -
git stash show
查看堆栈中最新保存的stash和当前目录的差异
举个例子
-
修改.gitignore文件,新建test.txt文件。再执行stash发现新增文件不会被存储;
-
git add之后再stash发现工作区是干净的;
-
说明没有在git版本控制(git add)中的文件,不能被git stash 保存;
-
最后通过git stash pop恢复。
λ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .gitignore
Untracked files:
(use "git add <file>..." to include in what will be committed)
test.txt
no changes added to commit (use "git add" and/or "git commit -a")
D:\learning\git\timed_tasks (master -> origin)
λ git stash
Saved working directory and index state WIP on master: 542a055 create .gitignore
D:\learning\git\timed_tasks (master -> origin)
λ git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
test.txt
nothing added to commit but untracked files present (use "git add" to track)
D:\learning\git\timed_tasks (master -> origin)
λ git add test.txt
D:\learning\git\timed_tasks (master -> origin)
λ git stash
Saved working directory and index state WIP on master: 542a055 create .gitignore
D:\learning\git\timed_tasks (master -> origin)
λ git stash list
stash@{0}: WIP on master: 542a055 create .gitignore
stash@{1}: WIP on master: 542a055 create .gitignore
stash@{2}: WIP on (no branch): 542a055 create .gitignore
D:\learning\git\timed_tasks (master -> origin)
λ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
D:\learning\git\timed_tasks (master -> origin)
λ git stash show
test.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
D:\learning\git\timed_tasks (master -> origin)
λ git stash pop
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: test.txt
Dropped refs/stash@{0} (b69da2894d5e7f511be18277c5a0cd4582fbf453)
D:\learning\git\timed_tasks (master -> origin)
λ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: test.txt
Tip:如果你修改的所有文件都不想要了怎么办?可通过git stash清空,懂吧?
λ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: test.txt
D:\learning\git\timed_tasks (master -> origin)
λ git stash
Saved working directory and index state WIP on master: 542a055 create .gitignore
D:\learning\git\timed_tasks (master -> origin)
λ git stash clear
D:\learning\git\timed_tasks (master -> origin)
λ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean