Git基础

1、前期准备

Step1:注册Github账号,注册地址:https://github.com/
Step2:由于你的本地 Git 仓库和 GitHub 仓库之间的传输是通过SSH加密的,所以我们需要配置验证信息:
使用以下命令生成 SSH Key:
ssh-keygen -t rsa -C "youremail@example.com"
后面的 your_email@youremail.com 改为你在 Github 上注册的邮箱,之后会要求确认路径和输入密码,我们这使用默认的一路回车就行。
Setp3:成功的话会在 ~/ 下生成 .ssh 文件夹,进去,打开 id_rsa.pub,复制里面的 key。
Step4:回到 github 上,进入 Account => Settings(账户配置)
Step5:左边选择 SSH and GPG keys,然后点击 New SSH key 按钮,title 设置标题,可以随便填,粘贴在你电脑上生成的 key。
Step6:为了验证是否成功,输入以下命令:
ssh -T git@github.com
中间提示输入yes,然后返回success就表示已经成功链接上Github了

2、创建项目

Step1:登录Github后点击" New repository "
Step2:在Repository name 填入 first-project(远程仓库名) ,其他保持默认设置,点击Create repository按钮,就成功地创建了一个新的Git仓库
Step3:本地git init初始化后,git remote add 添加远程仓库,或者直接git clone下来

3、Git基础认知

Git分为工作区、暂存区、版本库
工作区:就是你在电脑里能看到的目录。
暂存区:英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。

HEAD可以看做一个游标,指向哪里就是当前操作哪里。
git add 将工作区文件更新到暂存区
git commit 将暂存区文件更新到版本库
git reset HEAD 将版本库文件更新到暂存区,工作区不受影响
git rm --cached <file> 删除暂存区文件,工作区不受影响
git checkout . 或者git checkout -- <file> 将暂存区文件更新到工作区,会清除工作区中未添加到暂存区的改动
git checkout HEAD . 或者 git checkout HEAD <file> 会用HEAD指向的master分支中的全部或者部分文件替换暂存区和工作区的文件,会清除暂存区和工作区中未提交的改动

workspace:工作区
staging area:暂存区/缓存区
local repository:本地仓库
remote repository:远程仓库

4、Git命令

创建仓库命令

git init 初始化仓库,会生成一个.git目录,默认创建master分支

git clone 拷贝一份远程仓库,也就是下载一个项目
git clone <仓库路径> 将仓库文件拷贝到本地
git clone <仓库路径> <重命名> 将仓库文件拷贝到本地并重命名

提交与修改

git add 添加文件到仓库
git add file 添加本地指定修改文件到暂存区
git add . 添加本地所有修改文件到暂存区

git status 查看仓库当前状态,显示有变更的文件
git status 查看仓库当前状态,显示有变更的文件
git status -s 输出结果相对简单

git diff 比较工作区与暂存区文件的差异
git diff 比较工作区与暂存区文件的差异
git diff <file> 查看文件修改内容
git diff --cachedgit diff --staged 查看暂存区与仓库的区别
git diff HEAD 查看工作区与仓库的区别
git diff --stat 显示摘要而非整个diff
git diff b325c da985 比较仓库b325c与da985两个节点的区别

git commit 提交暂存区文件到本地仓库
git commit 提交暂存区文件到本地仓库
git commit -m ‘提交注释’ 提交代码的注释
git commit -a 将add 和commit操作合并操作
git commit -am ‘提交注释’ 表示add之后commit并提交注释
git commit --amend 取消原有提交,进行一次新的提交,产生新的提交节点
git commit --no-verify 跳过eslint验证提交

git reset 回退版本,把当前分支指向另一个位置,并且有选择的变动工作区和暂存区
git reset [--soft | --mixed | --hard] [HEAD] 回退版本,请看场景1
--mixed为默认,可以不带该参数,用于将远程仓代码更新到暂存区,工作区文件不变
git reset 等同于 git reset,回退所有内容到最后一次提交
git reset HEAD^ 回退所有内容到上个版本
git reset HEAD^ hello.js 回退hello.js到上个版本
git reset 052e 回退到指定当前仓库的052e版本
--soft 用于回退到某个指定版本,暂存区和工作区都不变
git reset --soft HEAD~3 回退到上上上个版本
--hard 撤销工作区所有未提交的内容,并删除之前的所有信息提交,暂存区和工作区都退回到上个版本
git reset --hard HEAD~3 回退到上上上个版本
git reset --hard bae128 回退到某个版本回退点之前的所有信息
git reset --hard origin/master 将本地的状态回退到和远程的一样

git rm 删除工作区文件
git rm <file> 将文件从暂存区和工作区删除
git rm -f <file> 删除之前有改动并且放到暂存区,需要用强制删除选项-f
git rm --cached <file> 暂存区移除,工作区保留,使用--cached选项
git rm -r * 递归删除,删除当前目录下所有的文件和子目录
git rm -r <目录> 删除指定目录下所有的文件和子目录

git mv 移动或重命名工作区文件
git mv [file] [newfile] 将文件file移动到newfile或者重命名为newfile

提交日志

git log 查看历史提交记录
git log 查看历史提交记录
git log --oneline 查看历史记录的简洁版
git log --graph 查看历史中什么时候出现了分支与合并,通过拓扑图展示
git log --reverse 逆向显示所有日志
git log --author=wang --oneline -5 查看wang前5次的简洁版提交记录
git log --online --before={3.weeks.ago} --after={2021-01-01} --no-merges 查看2021年1月1日到3周前的所有提交记录,--no-merges隐藏合并提交
查看更多git log命令:http://git-scm.com/docs/git-log

git blame 查看指定文件的修改记录
git blame <file> 以列表形式查看指定文件的历史修改记录

git tag 给重要版本加标签
git tag 查看所有标签
git tag v9 添加标签v9
git tag -d v9 删除标签v9
git tag -a v9 添加标签v9,并打开弹窗添加标签注释
git tag -a v9 85sd23 给85sd23提交添加标签v9和注释
git tag -a v9 -m ”版本v9” 添加标签v9,并添加注释”版本v9”
git show v9 查看v9的注释以及关联的commit记录
git push origin [tagname] 将tag推送到远端
git push --tagsgit push origin --tags 将所有tag推送到远端
git tag -d tag-name 删除本地tag
git push origin :refs/tags/tag-name 删除远程tag

远程操作

git remote 远程仓库操作
git remote 显示所有远程仓库
git remote -v 显示所有远程仓库及其实际链接地址
git remote show [remote] 显示某个远程仓库信息,[remote]远程仓库地址
git remote add [shortname] [url] 添加远程版本库,[shortname]本地版本库别名,[url]远程版本库地址
git remote rm [shortname] 删除远程仓库,[shortname]仓库别名
git remote rename [oldname] [newname] 修改仓库名
git remote prune thunk 同步远端与本地分支,删除本地多余分支

git fetch 从远程获取代码库
git fetch [origin] 获取远程分支更新的数据,[origin]为分支别名,然后紧接着必须执行git merge [origin]/[branch],将更新合并到当前分支

git pull 下载远程代码并合并,其实就是git fetchgit merge的简写,请看问题区别1
语法结构:git pull [远程仓库名] [远程分支名]:[本地分支名]
git pull 下载所有远程分支代码
git pull origin master 将远程仓库的master分支拉取下来,与本地当前(master)分支合并
git pull origin master:brantest 将远程仓库的master分支拉取下来,与本地brantest分支合并

git push 上传远程代码并合并
语法结构:git push [远程仓库名] [本地分支名]:[远程分支名]
git push origin master:master 将本地master分支推送到远程master分支,远程分支名与本地分支名相同,可以省略远程分支名git push origin master
git push --force origin master 当本地版本与远程版本有差异,可以--force强制推送,也可以git push origin master -f
git push origin --delete master 删除远程仓库的master分支

分支管理

git branch 查看所有本地分支
git branch -r 查看所有远端分支
git branch -a 查看所有分支
git branch <branch-name> 创建分支
git branch -d <branch-name> 删除分支
git branch -m old_name new_name 修改本地分支名,远端分支名无法修改,只能删除重推

git checkout 用于从历史提交(或者暂存区)中拷贝文件到工作区,也可切换分支
git checkout file 从暂存区拷贝file覆盖工作区文件
git checkout HEAD~ file 从仓库当前提交节点的父节点拷贝file文件覆盖工作区和暂存区文件
git checkout <branch-name> 切换分支,切换分支会将该分支直接覆盖当前工作区和暂存区内容,分支内容为创建分支时候的内容,请看场景2
git checkout master~3|标签| SHA-1值 切换一个没有名字的分支,会得到一个匿名分支,它不属于任何一个分支,它只是一个节点,比如 git checkout v5.0.2.300 也可以切换到版本v5.0.2.300(节点上的标签),但由于不属于任何一个分支,所以叫做detached HEAD(被分离的HEAD标识),这种状态下面可以编译打包安装,然后切回分支,但是涉及到提交会比较麻烦。直接进行提交产生节点2不会更新任何一个现有分支,当切换回master之后。该分支节点2的提交就会被丢弃,不会再有东西引用这个分支节点。如果想保存这个状态,可以在该节点创建一个分支并切换过去,再提交就可以记录下来了
git checkout -b <branch-name> 创建新分支并立即切换到该分支

git merge 合并分支,可多次合并到统一分支,也可选择在合并之后直接删除被并入的分支,合并前索引必须和当前提交相同。如果另一个分支是当前提交的祖父节点,那么合并命令将什么也不做。 另一种情况是如果当前提交是另一个分支的祖父节点,就导致fast-forward合并。指向只是简单的移动,并生成一个新的提交。否则就是一次真正的合并,请看场景3
git merge <branch-name> 将指定分支合并到当前分支。合并时,如果两个分支修改了同一个文件的同一行代码,就会出现合并冲突,此时将冲突文件修改后,通过 git add 操作可以取消文件的冲突状态

git cherry-pick 复制一个提交节点并在当前分支做一次完全一样的新提交,请看场景4
git rebase 代码合并,与git merge不同,git merge是将两个父分支合并进行一次提交,提交历史不是线性的,git rebase在当前分支上重演另一个分支的历史,提交历史是线性的,本质上是线性的自动化git cherry-pick
git rebase master 将当前分支的所有提交记录在master上重新提交一遍,并把分支指向新节点,原有提交记录废弃,请看场景5
git rebase --onto master 169a6 限制从169a6开始(不包括169a6)在master上重演,请看场景6

暂存区管理

git stash 保存本地修改内容,建立一条stash信息,默认的说明信息是最后一次提交的节点号和提交说明
git stash save ‘说明信息’ 保存本地修改内容,并指定说明信息
git stash list 查看当前仓库下所有stash条目,每一条stash用stash@{n}标识
git stash pop [stash] 获取stash内容,默认第一条(即stash@{0}),可以通过stash@{n}来指定获取stash条目
git stash drop [stash] 丢弃stash内容,默认第一条(即stash@{0}),可以通过stash@{n}来指定丢弃stash条目
git stash clear 清除所有stash条目
git show stash@{n} 查看指定stash条目内容
注意:
git stash不针对特定的分支,切换分支后,stash内容不变,所以弹出时要小心;
git stash pop或者drop后,stash的序号会自动改变,连续弹出时要注意。

HEAD说明

HEAD、HEAD~0 表示当前版本
HEAD^、HEAD~1 表示上一个版本
HEAD^^、HEAD~2 表示上上个版本
HEAD^^^、HEAD~3 表示上上上个版本

配置部分

git config --list 显示当前配置信息
git config -e 编辑当前仓库
git config -e --global 编辑系统上所有仓库
git config --global user.name ‘wang’ 设置提交代码时的用户信息,去掉global只对当前仓有效
git config --global user.email 879@qq.com 设置提交代码时的用户信息,去掉global只对当前仓有效

其他指令

mkdir dirname 创建目录
touch file 创建文件
vim file 修改文件
cat file 读取文件
head -3 file 显示文件前3行
ls 查看当前路径下的所有文件以及文件夹

5、拓展

拓展1:git文件结构与说明

.git文件夹下面有config文件、COMMIT_EDITMSG文件、refslogs文件夹等:

  • config文件说明分支配置
  • COMMIT_EDITMSG文件保存最新的提交信息
  • refs文件夹下面的heads保存本地库的最新commit id,remotes中每个文件夹代表一个远程库,远程库中每个文件夹代表一个分支,其中保存该分支最新的commit id,stash保存暂存区的最新commit id
  • logs文件夹保存着与refs文件夹下对应分支(包括本地库、所有远端库、stash)的操作记录

参考区别1
git commit 更新本地库最新commit id
git push 更新本地库关联的远端库的commit id

拓展2:多本地分支操作

git checkout –b branchname新建切换分支的时候会将原有分支的所有信息(即git log的所有操作日志体现的信息)都一起复制,所以一般来说多本地分支操作会保留一个主本地分支,这个分支和远程origin的分支关联,该分支只进行pull操作,保证最新的情况下进行分支创建。
假设本地分支main与远程仓库origin的main分支关联,此时修改本地main分支提交远程trunk的main分支,操作节点为节点1,且trunk还没merge到origin,那么此时pull本地main分支就会报错。或者此时新建本地main2分支并切换过去进行新的开发,那么main2分支带有main分支的所有提交信息,包括提交trunk但没merge到origin的提交(即节点1),理论上和main分支一样,没什么区别,新建这个main2分支起不到任何作用,同时从main新建切换到的main2的时候不能保证本地main分支是最新代码,main2也就不是最新代码,此时修改main2提交就会报错,同时main2也没有和origin关联,也无法进行pull,所以无法进行任何操作。
解决上述问题的办法就是先将本地main分支代码新建切换到main2,此时main2包含提交节点1,然后回到本地main分支,再reset到节点1之前的版本,再将代码pull到最新,此时再新建切换到新的分支main3写新的需求然后提交合并。
最正确做法是将与远程仓库origin的main分支关联的本地main分支作为本地主分支,只进行pull操作,如果需要开发的话,将本地main分支pull到最新后新建并切换到分支main2、main3等等,再进行代码的编写提交。

6、区别

区别1:git fetchgit pull的区别

git fetch 更新本地库关联的远程库的commit id,然后git merge将远程库与本地库合并,更新本地库代码,同时更新本地库的commit id
git pull 更新本地库代码,更新本地库和关联的远程库的commit id
参考文献4以及拓展1
fetch+merge比pull安全
主要就是因为fetch之后可以查看diff再merge,pull不经过本地用户同意就直接更新本地代码,一旦出错,很难找到错误原因

7、场景

场景1:reset回退版本

假设修改了两个文件1.js和2.js
git add . 提交到暂存区
git reset HEAD 1.js 将暂存区的1.js清除,就是将仓库中的1.js替换到暂存区
git commit 此时只提交2.js,暂存区中只有2.js被修改了
git commit –am ‘提交注释’ 此时1.js就会被直接提交到仓库

场景2:checkout分支切换

假设现在master分支有文件1.js,此时创建分支master2,然后不切换分支直接创建文件2.js并提交到master,此时master分支有两个文件,而master2分支只有文件1.js

场景3:merge操作逻辑说明

默认把当前提交(ed489 如下所示)和另一个提交(33104)以及他们的共同祖父节点(b325c)进行一次三方合并。结果是先保存当前目录和索引,然后和父节点33104一起做一次新提交。

场景4:cherry-pick操作逻辑说明

场景5:rebase操作逻辑说明

该命令在topic分支中进行,而不是master分支,在master分支上重演,并且把分支指向新的节点。注意旧提交没有被引用,将被回收。

场景6:rebase指定重演开始节点

在master分支上重演当前分支从169a6以来的最近几个提交,即2c33a。

场景7:提交代码冲突,或者没有pull就push

如果没有push上去:
方法1:git reset commitid将暂存区代码回退到上一节点(工作区不变),然后git pull拉代码,解决冲突之后git commitgit push提交代码即可
方法2:git pull --rebase origin master,该方法的意思是取消提交的commit并临时保存为补丁,然后将远程代码同步到本地,再将补丁合并到本地,接下来就可以push代码了
如果通过--force强制推上去了:
这种情况已经覆盖了别人的commit,只能让别人再提交一次后,我们再将代码pull下来,如果我们--force提交的代码还在就不用做任何处理,如果不在了只能再次提交

场景8:新建本地/远程分支,删除本地/远程分支

git checkout -b <branch-name> 新建切换本地分支
git push --set-upstream <remote-name> <local-branch-name>:<remote-branch-name> 推送本地分支到远程,本地分支推送到远程服务器时,远程分支自动创建,一般远程分支名和本地分支名相同,命令可简化为git push --set-upstream <remote-name> <branch-name>--set-upstream 参数用来关联本地分支和远程分支
git push <remote-name> --delete <branch-name> 删除远程分支
git branch -d <branch-name> 删除本地分支

场景9:分支合并

将分支a的修改代码合并到分支b上去:
git checkout 分支b 切换到被合并的分支b
git merge 分支a 将分支a代码合并到当前分支b
git status 查看合并过来的代码
git push 直接push到远程,无需填写目标分支和注释

场景10:修改commit信息

1、git log --oneline -5
查看最近5次commit的简要信息,输出信息为:简短commitID commit_message,可以根据需要查看最近n次的提交
也可以git log -5,输出信息相对详细些,commitID为完整的,这里只需要加上参数--oneline查看简短commitID即可
2、git rebase -i <简短commitID>
如果需要修改从上往下第2个commit_message,这里的简短commitID为上面输出信息的第3个,以此类推
在弹出的窗口中,以VIM编辑方式显示了最近两次的提交信息
3、(按照VIM操作)按i键,进入编辑模式,将想要修改的提交前的pick改为reword,如果需要修改多个,也可以将对应的多个pick改为reword
4、(按照VIM操作)按ESC键 再按 shift + : 然后输入wq(w是保存,q是退出) 按回车键
5、在弹出的窗口中,按i进入编辑模式,就可以修改commit_message了
6、(按照VIM操作)按ESC键 再按 shift + : 然后输入wq(w是保存,q是退出) 按回车键(同第4步)
如果第3步中修改了多个pick为reword,则会多次弹出修改界面,重复第5~6步即可
7、再使用第1步的命令查看一下修改结果,git log --oneline -5或者git log -5,查看修改是否已经完成
8、最后强制push上去git push --force

快捷操作:
1,修改最近一次的commit 信息
  git commit --amend
  然后就会进入vim编辑模式
2,比如要修改的commit是倒数第三条,使用下述命令:
  git rebase -i HEAD~3
3, 退出保存 :wq
4,执行 git rebase --continue
5,执行 git push -f 推送到服务端。

8、参考文献

1.https://learngitbranching.js.org/?locale=zh_CN
2.https://www.runoob.com/git/git-tutorial.html
3.http://marklodato.github.io/visual-git-guide/index-zh-cn.html
4.https://blog.csdn.net/a19881029/article/details/42245955

posted @ 2021-03-25 12:18  木-鱼  阅读(55)  评论(0)    收藏  举报