【前端打怪升级之Git篇】熟练掌握版本管理工具Git

Git在线练习平台:在线练习网站

Git学习资料:Pro Git(中文版)

初次运行Git相关配置

1 配置用户信息

#配置用户名和邮箱
#使用--global选项更改的配置文件位于用户主目录下,以后所有的项目都会默认使用这里配置的用户信息。要在某个特定项目中使用其他名字或者电邮,去掉--global选项重新配置即可,新的设定保存在当前项目的.git/config 文件里。

git config --global user.name 'xxx'
git config --global user.email 'xxx@xxx'

2 配置默认使用的文本编辑器

## git 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等合并工具的输出信息
git config --global core.eidtor vimdiff

3 配置差异分析工具

git config --global merge.tool  xxx

4 查看配置信息

 git config --list
    user.name=Scott Chacon
    user.email=schacon@gmail.com
    color.status=auto
    color.branch=auto
    color.interactive=auto
    color.diff=auto
## 有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:
git config user.name

5 获取帮助

git help <verb>
git <verb> --help
man git-<verb>
#eg: 学习config命令如何使用
git help config

Git使用过程中的小Tips

1. Tab键自动补全

2. Git命令设置别名

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit 
git config --global alias.st status

3. 设置新命令

# eg:设置新命令unstage:
git config --global alias.unstage 'reset HEAD --'
# 等价于
git unstage fileA
git reset HEAD fileA
# 设置新命令last:
git config --global alias.last 'log -1 HEAD'
git last
   commit 66938dae3329c7aebe598c2246a8e6af90d04646
   Author: Josh Goebel <dreamer3@example.com>
   Date: Tue Aug 26 19:48:51 2008 +0800

   test for current head

   Signed-off-by: Scott Chacon <schacon@example.com>

Git仓库操作

1. 将当前工作目录初始化新仓库

git init 
# 初始化后,当前目录下会出现一个名为 .git 的目录,所有 Git需要的数据和资源都存放在这个目录中。
#注意:目前仅仅是按照既有结构框架初始化好了里边所有的文件和目录,但还未开始跟踪管理项目中的任何一个文件。
# 将当前目录下的所有资源和文件纳入版本控制,执行:
git add .
# 对当前目录下特定文件进行跟踪然后提交,执行:
git add *.c
git add README
git commit -m "initial project version"

2. 从现有仓库克隆

# Git收取的是项目历史的所有数据(每一个文件的每一个版本),服务器上有的数据克隆之后本地也都有了。
# 克隆仓库的命令格式为 git clone [url]。例如:
$ git clone git://github.com/schacon/grit.git
# 当前目录下会创建一个名为grit的目录,其中包含一个.git 目录,用于保存下载下来的所有版本记录,然后从中取出最新版本的文件拷贝。
# 新建的grit目录包括项目中的所有文件。
# 如果希望在克隆的时候,自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:
$ git clone git://github.com/schacon/grit.git mygrit
# 【!】Git 支持许多数据传输协议。之前的例子使用的是 git:// 协议,也可以用 http(s):// 或者 user@server:/path.git 表示的 SSH 传输协议。

3. git上传本地项目到远程仓库

步骤1:初始化本地仓库

git init # 初始化本地仓库
git add . # 将本地所有文件放入到git的缓存区
git commit -m "feat:备注信息" #将缓存区的修改提交到git本地仓库

步骤2:在自己的github上创建一个空的仓库,名称为FoodKG,如下图
在这里插入图片描述

  • 复制git项目,这里有https 和ssh两种模式,我们这里使用https 模式。
    在这里插入图片描述
    步骤3:本地项目关联github项目
# 使用在第二步得到的地址,在命令窗口输入git remote add origin https://github.com/Natsumeo/FoodKG.git,该命令表示将本地仓库关联远程仓库
git remote add origin https://github.com/Natsumeo/FoodKG.git
#将本地项目推到远程的master主分支上,会提示成功上传至github,这个命令再第二次提交可直接输入git push。
git push -u origin master 

Git分支操作

1. 何为分支

1-Git中的分支其实本质上仅仅是个指向commit 对象的可变指针。
2-Git使用master作为分支的默认名字。
3-若干次提交后,其实已经有了一个指向最后一次提交对象的master分支,它在每次提交的时候都会自动向前移动。
4-分支其实就是从某个提交对象往回看的历史。

在这里插入图片描述

2. 创建新分支

git branch testing 
#在当前commit对象上新建一个分支指针
#Git保存一个名为HEAD的特别指针用于指向你正在工作中的本地分支(可将HEAD想象为当前分支的别名)。Git分支实际上仅是一个包含所指对象校验和(40个字符长度 SHA-1字串)的文件,所以创建和销毁一个分支就变得非常廉价。新建分支就是向一个文件写入41 个字节(外加一个换行符)那么简单,当然也就很快了。
#运行git branch 分支名命令仅仅是建立了一个新分支但是不会自动切换到该分支中去。

在这里插入图片描述

2.切换分支

git checkout testing

在这里插入图片描述

3.新建并切换到新分支上

$ git checkout -b iss53 #新建并切换到分支iss53上
   Switched to a new branch "iss53"
# 相当于执行以下命令:
$ git branch iss53
$ git checkout iss53

在这里插入图片描述

4.从master分支所在点分化出hotfix分支

git checkout master
git checkout -b 'hotfix'
    Switched to a new branch "hotfix"
vim index.html
git commit -a -m 'fixed the broken email address'
    [hotfix]: created 3a0874c: "fixed the broken email address"
    1 files changed, 0 insertions(+), 1 deletions(-)

在这里插入图片描述

5.将hotfix分支合并进master分支

git checkout master
git merge hotfix 
    Updating f42c576..3a874c

# master 分支所在提交对象是要并入的 hotfix 分支的直接上游
# Git只需把 master 分支指针直接右移,即如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,
#只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)
    Fast forward 
    README | 1 -
    1 files changed, 0 insertions(+), 1 deletions(-)
    
git branch -d hotfix  #hotfix分支完成自己的使命可以删除
     Deleted branch hotfix (3a0874c).
git checkout iss53
    Switched to branch "iss53"
vim index.html
git commit -a -m 'finished the new footer [issue 53]'
    [iss53]: created ad82d7a: "finished the new footer [issue 53]"
    1 files changed, 1 insertions(+), 0 deletions(-)

6. 查看所有分支

git branch -r #查看远程分支
git branch  #查看本地分支

7. 拉取远程分支到本地

# 1-需要本地分支和远程分支建立映射关系
# 在本地仓库新建本地分支xxx,并自动切换到新建的本地分支xxx,同时远程分支xxx的代码也拉取到了本地分支xxx中。
# 采用这种方法建立的本地分支会和远程分支建立映射关系。
# 本地分支名和远程分支名保持一致
git checkout -b 本地分支xxx origin/远程分支xxx 

#2-不需要本地分支和远程分支建立映射关系
# 使用这种方式会在本地仓库新建本地分支xxx,但是并不会自动切换到新建的本地分支xxx,需要手动checkout
# 远程分支xxx的代码也拉取到了本地分支xxx
# 采用这种方法建立的本地分支不会和远程分支建立映射关系
git fetch origin 远程分支xxx:本地分支

8. 将本地分支推送到远程

# 1-远程先开好分支然后拉取到本地
git checkout -b feature-brach origin/feature-branch #检出远程的feature-branch分支到本地

#2-本地先开好分支然后推送到远程
git checkout -b feature-branch
git push -u origin feature-branch #首次推的时候将远程分支设置为要推分支的upstream,下次可直接git pull|push feature-branch
git push origin feature-branch:feature-branch # 推送本地的feature-branch(冒号前)分支到远程origin的feature-branch(冒号后)分支(没有会自动创建) 

9. 删除分支

注:
|管道命令:用于将一串命令串联起来。前面命令的输出可以作为后面命令的输入
grep 搜索过滤命令:使用正则表达式搜索文本,并把匹配的行打印出来
xargs参数传递命令:用于将标准输入作为命令的参数传给下一个命令
管道命令与xargs命令的区别:管道是实现将前面的标准输出作为后面的标准输入,xargs是实现将标准输入作为命令的参数
# 删除本地分支(分支已被推送且合并到远程分支)
git branch -d 分支xxx

# 强制删除本地分支(分支未被推送或合并到远程分支)
git branch -D 分支xxx

# 删除除当前分支外的所有分支
git branch | xargs git branch -d

# 删除分支名包含指定字符的分支
git branch | grep ‘dev*’ | xargs git branch -d

# 删除远程分支
git branch -a  # 查看所有分支,其中remotes/origin/xxx 为远程分支
git push origin --delete 远程分支XXX

# —————回滚merge到master的分支———————
Merge: a421519da 9d22ee805
Author: xxx <xxx@qq.com>
Date:   Thu Dec 7 14:24:39 2023 +0800

Merge pull request #1290 in xxx/xxx from feature/xxx
to master - <merge-MERGE #PR-1290 ~Merge branch 'master' into feature/xxx
    >
#首先,你需要找到这个合并提交的hash值,你已经给出了这个值,即7ab55d102e0775a24f10757e8c401b4f75a083d8。
#然后,你可以使用git revert命令来撤销这个合并提交。因为这是一个合并提交,所以你需要使用-m选项来指定你想要撤销的父提交。通常,1表示合并前的主线分支,2表示被合并的分支。在这个情况下,你可能想要撤销主线分支的改变,所以你应该使用1作为参数。命令如下:
git revert -m 1 7ab55d102e0775a24f10757e8c401b4f75a083d8
#这个命令会创建一个新的提交,这个提交的内容是撤销合并提交的改变。你需要为这个提交输入一个提交信息,然后保存退出。
#最后,你可以使用git push命令来将这个撤销提交推送到远程仓库。

Git文件操作

1. 检查当前文件状态

git status

2. 查看已暂存和未暂存的更新

#使用文件补丁的格式显示具体添加和删除的行,可以查看尚未暂存(staged)的文件更新了哪些部分,该命令比较的是工作目录中当前文件和暂存区域快照之间的差异,即修改之后还没有暂存起来的变化内容。
#【!】git diff 是显示还没有暂存起来的改动,非本次工作和上次提交之间的差异
$ git diff  
#查看已经暂存起来的文件和上次提交时的快照间的差异
$ git diff --cached

3. 回到某次提交之前的状态

# 查看提交记录
git log
commit e180fa6b5068c278ac625ac89e358d49ab0709ba (HEAD -> master, origin/master, origin/HEAD)
Merge: c6d0d5c 4d05040
Author: xxx
Date:   Fri Jul 30 10:17:45 2021 +0800

    Merge pull request #10 in x/qcs.fe.feature from feature/20210728/lichao/mtUesrOptsShow to master

commit 4d0504027ac20832096b4cc3edbc787fcac6f2c4 (origin/feature/20210728/lichao/mtUesrOptsShow, feature/20210728/lichao/mtUesrOpts
Show)
Author: xxx
Date:   Wed Jul 28 20:42:56 2021 +0800

    feat:修正控制逻辑

commit 880b3239964a172093c8e5c44a25cd71c11fc5e6
Author: xxx
Date:   Wed Jul 28 18:54:09 2021 +0800

    feat:测试完成

# 回到提交e180fa6b5068c278ac625ac89e358d49ab0709ba之前的状态
git reset e180fa6b5068c278ac625ac89e358d49ab0709ba

4. 撤销改动

# 【取消对文件的未提交修改:会永久地删除未提交更改!!!】
git checkout .# 取消对所有文件的更改
git checkout -- <文件的绝对/相对路径>

# 【取消暂存区中的更改】
git reset HEAD <文件的绝对/相对路径>

# 【修改最后一次提交】
git commit --amend #使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令,相当于有机会重新编辑提交说明,且将要提交的文件快照和之前的一样。
git commit -m "initial commit"
git add forgetten_file
git commit --amend
# 以上三条命令最终只会产生一个提交,第二个提交命令修正了第一个提交

# 撤销已经加到暂存区的内容
# step1: 确保你的工作目录中没有未提交的更改,可以使用 git status 命令来查看当前的状态
# step2: 如果有未提交的更改,请先提交或撤销这些更改。可以使用 git add . 命令将所有修改的文件添加到暂存区,然后使用 git commit -m "Commit message" 命令提交更改。
# step3: 接下来,使用以下命令将要撤销的文件从 Git 中移除,case如下👇
git rm --cached package-lock.json
# step4: 确保在 .gitignore 文件中添加了 package-lock.json,以防止将来再次将其添加到版本控制中。
# step5: 最后,使用git commit -m "xxx" 提交更改

5. 移除已经add的文件

# 不删除物理文件,仅将该文件从缓存中删除
git rm --cached '文件路径'
# 将该文件从缓存中删除,同时删除物理文件(不会回收到垃圾桶)
git rm -f '文件路径'
# 实际使用case:文件已经add到暂存区,还没有commit,此时不想要文件
# 方案一:清空已缓存的内容
git reset HEAD 
# 方案二:将该文件从暂存区删除
git rm --cached '文件路径'  

6.删除远程仓库的文件

# step1:预览将要删除的文件
# 加上 -n 这个参数,执行命令时,是不会删除任何文件,而是展示此命令要删除的文件列表预览。
git rm -r -n --cached '文件/文件夹名称'
# step2: 确定无误后删除该文件
git rm -r --cached 
# step3: 提交到本地并推送到远程服务器
git commit -m "提交说明"
git push origin master

7. 查看提交历史

git log #按照提交时间列出所有更新,最近的更新排在最上面
git log -p -2 # -p选项展开显示每次提交的内容差异,-2选项表示仅显示最近两次的更新
git log --stat # --stat选项仅展示简要的增改行数统计
git log --pretty=online #--pretty选项可指定使用完全不同于默认格式的方式展示提交历史,例:使用oneline将每个提交放在一行显示,适用于提交数很大的情况。此外,还有short、full和fuller等选项可以用

8. 恢复文件到指定版本

#1.首先,使用 git log 命令查看 commit 记录,找到你想要恢复 package-lock.json 文件的 commit 的哈希值(commit hash):
git log
#2.使用以下命令将 package-lock.json 文件恢复到指定的 commit:
git checkout <commit-hash> -- package-lock.json
#3.使用以下命令将恢复后的 package-lock.json 文件提交到版本库:
git add package-lock.json
git commit -m "恢复 package-lock.json 到指定的 commit"

Git revert 某次merge后再重新 merge代码被丢失

参考:
https://blog.csdn.net/u012175512/article/details/105858132
https://stackoverflow.com/questions/19379034/force-merge-after-reverting-merge-commit-int-git

#🙋问题:master分支merge feature分支后发现有问题无法上线,revert此次merge  (紧急回滚上线)
#❓原因:因为git第一次merge此分支了,revert只是在此分支上提交了一次"反向修改"(相当于新的commit).这merge和revert这两次都相当于commit
#💡解决:
#方案一:对 revert 的那次提交记录再次进行revert  (官方推荐方法),详见(https://stackoverflow.com/questions/19379034/force-merge-after-reverting-merge-commit-int-git)
git checkout master
# 从master拉一个新分支 revert_tmp
git checkout -b revert_tmp
# 找到 revert 的那条提交记录,注意了,revert 相关的会有两条记录,第一条是 revert,第二条是 revert 后 merge 的记录,这里取第一条
# 用revert_tmp分支revert之前的revert
git revert <版本号>
# 再用master分支合并此分支代码推到远程即可
git checkout master
git merge revert_tmp
git push

#方案二:强制物理覆盖重新提交一次(暴力解法)
#操作方法:从master拉个新分支出来,物理拷贝feature分支代码后提交, master再merge此分支

#方案三:master 分支reset 后 pull -f
#⚠️注意:一般master分支都有protect ,不让回滚提交,要去gitlab上关闭此保护  (所以此法适用于非master分支)
git checkout master
# 把master回滚merge之前的状态
git reset head^ --hard   
(git reset --head "<>")
# 强制推上去
git push -f
# 重新merge feature后再推远程即可
git merge feature
git push
# PS:git reset head^ --hard  :  head^表示回滚到上一个提交版本 --head 本地代码会被覆盖
# 🙆正规线上回滚操作流程:应该在每次上线打个tag,想回滚之间部署前一个tag
git revert < commit id > -m 1 
# 🤔️原理和拓展
# 1.git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
# 2.git reset是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。
# 3.在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值