您现在的位置是:首页 >其他 >git操作网站首页其他
git操作
基本概念:
基本概念:工作区、暂存区、版本库、远程仓库
- 工作区(Workspace):本地存放文件的地方。Git会知道这里的文件变更,如添加/修改/删除文件。
- 暂存区(Stage/Index):临时存放文件变更信息,事实上它是一个名为index的文件。
- 版本库(Repository):工作区有一个隐藏目录.git,它是Git的版本库,为了与远程仓库区分,将其明确称为本地版本库(Local Repository)。其中有一个HEAD指向当前版本库版本。
- 远程仓库(Remote Directory):托管代码的服务器
-
Directory:使用Git管理的一个目录,也就是一个仓库,包含我们的工作空间和Git的管理空间。
-
Workspace:需要通过Git进行版本控制的目录和文件,这些目录和文件组成了工作空间。
-
.git:存放Git管理信息的目录,初始化仓库的时候自动创建。【
git init
】 -
Index/Stage:暂存区,或者叫待提交更新区,在提交进入远程仓库之前,我们可以把所有的更新放在暂存区。【
git add <file>
】 -
Local Repo:本地仓库,一个存放在本地的版本库;HEAD只指向当前的开发分支(branch)。【
git commit -m <message>
】 -
Stash:隐藏,是一个工作状态保存栈,用于保存/恢复Workspace中的临时状态。【后续可以用于切换分支时暂存修改的文件】
Git文件操作
管理变更(git add/rm, git restore),解决工作区修改和git add问题
Git会跟踪并管理的是变更
-
撤销工作区变更(撤销对工作区文件的添加/修改/删除):
git restore <filename>
或git checkout -- <filename>
。 -
撤销暂存区变更(撤销git add/rm):
git restore --staged <filename>
或git reset HEAD <filename>
。
注意:
-
git restore --staged <filename>
只会撤销暂存区的更改,如果撤销工作区,还得执行git restore <filename>
-
git rm <filename>
等价于从工作区删除文件并将这一更改变更到暂存区,所以撤销时要同时撤销暂存区的更改,如下git rm README.md #在工作区删除README.md,并且这一变更被加到暂存区 git restore --staged README.md #撤销暂存区的变更(README.md的删除),注意,此时工作区文件还是没有变 git restore README.md #撤销工作区的变更,即工作区README.md文件被还原成删除前
版本回退(git reset),解决git commit后回退问题
实际上就是移动HEAD指向的位置(HEAD指向的版本就是当前版本)
用git log可以查看提交历史中各个版本的<commit_id>
用git reflog可以查看命令历史,即所有分支的所有操作记录(包括commit, reset, checkout, merge等操作)。
- 指定版本回退到<commit_id>:
git reset --hard <commit_id> #当前分支和HEAD均指向<commit_id>
- 回退到当前HEAD的上一个commit,此时会撤销暂存区变更(撤销commit和add):
git reset --hard HEAD~1 #HEAD~1表示上一个commit版本,如果是往上两个版本就是HEAD~2;当前版本就是HEAD
- 回退到当前HEAD的上一个commit,不撤销暂存区变更(撤销commit):
git reset --soft HEAD~1
总结:
查看命令( git log, git reflog, git diff)
- git log 查看提交历史。可加选项:
- –oneline 每行显示一个commit。例如显示9af21bf add README.md,那么<commit_id>前几个字符就是9af21bf。
- –all 显示所有分支的提交历史,否则只显示当前分支的提交历史。
- –graph 显示分支合并,以横线形式连接曾有过合并的各个提交。
- git reflog 查看命令历史。
- git diff 查看工作区和暂存区差异。
- git diff --cached 查看暂存区和版本库差异。
- git diff – HEAD~1 查看工作区和版本库的差异。HEAD1可以改成HEAD、HEAD2等等。
- git diff HEAD HEAD~1 查看版本库HEAD与版本库HEAD~1之间的差异(最新的commit和上一次commit)。
本地仓库的各项管理命令可以参照下图方便记忆
本地分支管理
查看/创建/切换/删除分支(git branch, git switch)
查看本地分支:
git branch #要查看远程分支则加上选项-r,查看所有分支则加上选项-a
创建分支:
git branch <name>
切换分支:
git switch <name> #等价于git checkout <name> (注意:switch命令是git 2.23版本的新命令)
创建+切换分支:
git switch -c <name> #等价于git checkout -b <name>
删除普通分支:
git branch -d <name>
强制删除未合并的分支:
git branch -D <name>
合并分支(git merge)
快速合并(Fast-forward):合并当前分支(旧)到某分支(新)的位置。
git merge <name> #某分支名为<name>,会将某分支历史覆盖
例如:
快速合并后
非快速合并:合并当前分支+某分支,产生一个新的提交,合并到这个新提交的位置,这样可以保存之前的分支历史。
git merge --no-ff -m <message> #<message>表示新提交的信息
非快速合并后
修改时切换分支(git stash, git cherry-pick)
在一个分支上开发,但是此时,突然发现有一个紧急的bug需要修复,需要切换新的节点,而当前的某个文件还没有写完,暂时无法commit到版本库中,可以使用git stash
git stash可以把当前工作状态储存到stash这个栈之中,等以后出栈,即可还原现场,继续工作。
当前工作状态入栈后,再用git status可以看到"无文件要提交,干净的工作区"。
案例:
- 假设要在feature分支上修复bug,那么就在feature分支上创建并切换到bug分支(命名为issue-101)。假设修复bug就是修改README.md文件,修复完就commit,然后,再切换回feature分支,将bug分支与feature分支进行非快速合并,此时,已经完成了bug修复,可以重返当时储存的工作状态了
#现在位于feature分支进行操作,然后创建并切换到bug分支
git stash
git switch -c issue-101 #bug分支
echo "Fixed the bug of README.md" >> README.md
git add README.md
git commit -m "fix bug 101"
git switch feature
git merge issue-101 --no-ff -m "merged bug fix 101"
git stash pop #将栈顶的工作状态出栈,同时删除栈顶内容
现在我们已经修复了feature分支上的bug,假设master分支上也要修复相同的bug,怎么办?
不用那么麻烦的再做一遍修复bug、合并分支的工作,可以用git cherry-pick <commit_id>
,它能把bug分支的commit操作直接"复制",然后commit到当前分支:
git switch master
git stash # 如果master分支上有待提交的变更,那么必须先保存状态
git cherry-pick 8436eb8 #8436eb8是修复bug的<commit_id>,可用git log查看为8436eb8 (issue-101) fix bug 101
git stash pop
其他指令:
- git stash list # 查看stash内容
- git stash apply stash@{0} #栈顶为stash@{0},栈顶的下一个为stash@{1}
- git stash drop 删除栈顶内容
注意
- git stash apply并不会删除栈内的任何内容,但git stash pop将栈顶工作状态出栈的同时也会删除栈顶的内容。
远程仓库管理
克隆远程仓库(git clone)
创建本地仓库的方法之一是克隆远程仓库
git clone <url> #远程服务器的URL
- 当你克隆某个远程仓库后,默认情况下Git会自动设置本地master分支跟踪克隆的远程仓库的master分支(或其它名字的默认分支),并且默认设置远程仓库在本地的别名是origin。
实际上克隆命令是git clone ,表示克隆⼀个指定repo到本地,其指定repo可以是本地⽂件系统或者由HTTP或SSH指定的远程路径。
添加/删除远程仓库(git remote add/rm)
(1)添加远程仓库关联
实际就是给远程仓库服务器地址起一个本地的别名/简称(习惯命名为origin)。
将远程服务器地址<url>
映射为 本地对远程服务器的别名<shortname>
,命令格式如下:
git remote add <shortname> <url> #将<shortname>与<url>关联,以后就可以用<shortname>代替<url>
例如在本地git终端中输入
git remote add origin git@github.com:nefu-ljw/ACM-Algorithm.git
这样以后,就可以在命令行中使用字符串origin代替整个git@github.com:nefu-ljw/ACM-Algorithm.git。
(2)删除远程仓库
git remote rm <shortname> #删除别名<shortname>及其对应的远程服务器地址
一旦使用这种方式删除了一个远程仓库,那么所有和这个远程仓库相关的远程跟踪分支以及配置信息也会一起被删除
推送远程仓库(git push)
将本地仓库的分支<branch>
推送到远程服务器<remote>
,命令格式如下:
git push <remote> <branch> # 这里的<remote>就是之前添加的远程服务器地址的别名<shortname>
如果是第一次将本地分支master推送到远程服务器origin,则使用-u选项指定一个默认服务器【可能当前分支与多个服务器存在跟踪关系】:
git push -u origin master #之后会产生远程分支origin/master,并且本地分支master跟踪远程分支origin/master
抓取/拉取远程仓库(git fetch, git pull)
如果远程服务器的数据有更新,要将这些新数据下载到本地,可以用git fetch或git pull。
(1)抓取远程仓库(fetch)
a. 访问远程服务器,从中抓取所有所有分支的更新:
git fetch <remote> #从远程仓库服务器<remote>中抓取所有分支的更新
b. 如果只想取回特定分支的更新,可以指定分支名:
git fetch <remote> <branch> #例如git fetch origin master
(2)拉取远程仓库(pull,即fetch+merge)
a. 取回远程服务器<remote>
某个分支<remote_branch>
的更新,再与本地的指定分支<local_branch>
合并:
git pull <remote> <remote_branch>:<local_branch>
示例,取回远程服务器origin(远程仓库地址别名)的分支feature,与本地分支master合并:
git pull origin feature:master
b. 如果远程分支是与本地当前分支合并,则可省略:<local_branch>
,如下:
git pull origin feature #等价于先fetch,再merge
这会让feature在FETCH_HEAD中临时保留一个副本,并更新远程跟踪分支origin/feature。
等价于,先fetch,再merge:
git fetch origin #将远程服务器origin的所有分支取回到本地,比如远程分支feature的本地副本为origin/feature
git merge origin/feature #将远程分支origin/feature合并到当前分支
c. 如果当前分支与远程分支存在跟踪关系,则可省略<remote_branch>:<local_branch>
,如下:
git pull origin #自动尝试合并 当前分支跟踪的远程分支→当前分支
经常有人在不给任何参数的情况下使用git pull,这一般相当于git pull origin。
git fetch:获取远程服务器的更新到本地,不自动合并到本地分支。
git pull:获取远程服务器的更新到本地,自动合并到本地分支。
略、、、
参考博文