4

1. 拉取远程分支到本地

如果本地没有代码,首先需要git clone项目到本地,此时clone下来的是master分支,然后再去拉取其他分支,
下面是两种方式

1.git fetch origin <远程分支名>:<本地分支名>
此时会在本地就有分支了,但是没有跟远端分支建立映射关系,也不会切换到新的分支
git fetch origin <远程分支名> 这种方式只是从远端拉取了分支,但是本地没有新分支
使用 git branch -r 查看, 一般结果为
origin/HEAD -> origin/master
origin/master
origin/<远程分支名>

分支管理-多人协作

2.本地新建分支, 把此分支放入其中
git checkout -b <本地分支名> origin/<远程分支名>
这种方式会建立映射关系

为什么要建立映射关系?
不建立映射关系每次push或者pull都需要指定远端分支

怎样建立映射关系?
git拉取远程分支并创建本地分支
git branch -vv查看分支的映射关系
切换到分支git branch -u origin/分支名手动建立当前分支和远端分支的映射关系

2. push代码到远程分支

首先切换到要push代码的本地分支上,然后git push origin <远程分支>
在本分支下直接git pull拉取对应远程分支。

3.git add . git commit -m '完成功能'后 push前 撤销commit,但保留之前的修改

别人的方法,尝试了没效果:

  1. 找到上次Git commit的 id
         git log 
         找到你想撤销的commit_id
    2.  git reset --hard commit_id
          完成撤销,同时将代码恢复到前一commit_id 对应的版本。
  2. git reset commit_id 
         完成Commit命令的撤销,但是不对代码修改进行撤销,可以直接通过git commit 重新提交对本地代码的修改。

后面搜到的方法,起了作用:
git reset --soft HEAD^

今天同事遇到个问题,就是有三个commit,并且已经push到了remote,需要撤销中间的那条commit,保留第一条和第二条commit,使用reset -hard第二条commit hash后,后面的两个commit都消失了,没有达到想要的效果,现在就是恢复回来,那么从远端pull回来就可以了,然后git revert 中间的commit hash,达到了目的,参考了git reset revert 回退回滚取消提交返回上一版本

git使用情景2:commit之后,想撤销commit

3. git 删除本地分支-d -D的区别

-d
-D

feature/creditsCountSetting该分支下有没有merge好的代码所以做了提示,-D就是强制删除分支

4. git pull <远程主机名> <远程分支名>:<本地分支名>

现在的开发模式是只能从develop代码到本地,不能push到develop,新建功能或者修复bug都需要新建一个分支,然后push自己的分支到gitlab,然后发起merge request给同事,然他们review并merge到develop分支,那么就存在一个问题,直接merge到develop分支的话有可能会冲突,所以在push自己的分支前一定要拉取develop代码到自己的分支,在本地解决冲突,

  • 之前我的做法:
  • 自己分支commit代码
  • 切换到develop 然后 git pull
  • 再切换到自己的分支 执行git merge develop
  • 后来发现可以直接在本地分支拉取远端develop到当前的分支
    也就是 git pull origin develop
    因为拉取远端的分支到当前的分支,所以冒号后面的参数就省略了

    git pull命令

5. Commit message 和 Change log 自动生成markdown文件

类似于下面
image.png

conventional-changelog 就是生成 Change log 的工具,运行下面的命令即可

Commit message 和 Change log 编写指南
commitlint

6. git cherry-pick 将特定的commit记录合并到当前分支

一个picker分支基于develop,现在的代码都commit在picker分支,由于react升级到16所以又开了个分支在master分支,所以现在新建分支masterpicker基于master,然后将picker分支的一些commit合并到masterpicker,那么就需要使用cherry-pick命令,如果直接使用git merge 那么就会将所有的develop的代码都合并到了masterpicker分支。
git cherry-pick 使用指南

如果你现在的工作目录(work tree)里搞的一团乱麻, 但是你现在还没有把它们提交; 你可以通过下面的命令, 让工作目录回到上次提交时的状态(last committed state):

$ git reset --hard HEAD

7. push本地仓库到远端新的仓库

git remote -v可以查看本地仓库关联了几个远端仓库

  • 添加新的远端仓库 git remote add gitee https://gitee.com/balibabu/apollo-linter.git
  • 将develop分支推送到远端master分支git push -u gitee develop:master,不加上develop分支的话,push不了

8. 查看本地已经commit,但未push的代码

git cherry -v //查看本地已经commit,但未push的版本
git show xxxxx_version_id //查看版本中的具体代码

9. git stash 暂存代码

git add 以后往往切换分支的时候是切换不了的,那么就可以运行git stash暂存代码,git stash list 查看暂存代码记录,然后找到对应版本git stash apply stash@{1}撤销暂存

新建文件的时候发现git stash 并不起作用,那么怎么办呢?原来暂存分为两种情况:

  1. 文件已经被 git 跟踪,只是修改了代码(而不是新条件文件),我们可以使用 git stash 或 git stash save "注释" 来暂存修改。
  2. 如果有新添加的文件,那么就需要添加 -a 参数(如,git stash -a 或 git stash save -a "注释"),或先 git add . 然后再使用 git stash 或 git stash save "注释" 来暂存修改。再或者git stash save -u orgit stash save --include-untracked

git stash和git stash pop
git stash 暂存当前修改
你可能不知道的关于 Git stash 的技巧

10. git tag v1.0

创建本地taggit tag v1.0
将本地tag推送到远端git push origin --tags
获取远端taggit fetch origin tag V1.0
删除本地taggit tag -d V1.0
删除远端taggit push origin :refs/tags/V1.0
查看某个tag详细信息git show v1.0 比如谁在什么时候打的tag

如果我想在某个tag上build代码,发布到服务器,我们可以切换到改tag,就拿到了对应的代码

切换到某个taggit checkout v1.0
在从lodash master分支切换到标签4.17.11-es的时候使用git checkout v4.17.11-es会报错,直接用git checkout 4.17.11-es就可以切换,很奇怪。比对下发现有些库的tag是没加v前缀的,所以lodash直接git checkout 4.17.11-es就行了。
git checkout v1.0

同理可以切换代码到历史某次commit id
git checkout 170c521
比如怀疑当前代码有问题,历史某次提交可能是对的,然后切换到历史某次代码

切换到了历史,怎么切换回最新的代码?
直接git checkout master(分支名)
How to get back to most recent version in Git?

提示我代码无法提交,在本tag上新建个分支就可以正常的开发了
git checkout -b <new-branch-name> <tag-name>

git 打标签并推送tag到托管服务器
git切换到某个tag

10. git 修改用户名 邮箱

经常在公司和家里办公,提交代码到一个仓库,但是出现commit username不同的情况,那么需要在本仓库设置username和email

1.设置本仓库

git config user.name ""
git config user.email ""

git修改提交作者和邮箱

11. git 修改已提交的内容

git 修改已提交的内容

12. git rebase develop

  1. 在master下新建index.html文件
  2. git checkout -b develop 新建文件file.txt
    3.切回master 再新建bill分支 新建logo.txt 执行 git rebase develop

bill branch

  1. 切回master 再新建assassin分支 新建geek.txt 执行 git merge develop
    assassin branch

对比两图可以发现,在assassin分支有一条Merge branch 'develop' into assassin的记录而rebase是没这条记录的,也就是rebase提到的如果你想让"mywork"分支历史看起来像没有经过任何合并一样,但是在develop中提交的add file.txt记录还是在的

当然我们通常是pull远端的代码到当前的分支
git pull origin develop
git pull origin develop --rebase

简单对比git pull和git pull --rebase的使用

在执行git pull origin develop --rebase同一个commit产生了两条commitID,不知道是怎么产生的,

使用git rebase合并多次commit
聊下 git rebase -i
git rebase -i可以将多个commit合并为一个commit

13. You have not concluded your merge (MERGE_HEAD exists)

You have not concluded your merge (MERGE_HEAD exists) git拉取失败

14.为项目添加公私钥

git 多套公、私钥的配置以及使用

由于运行ssh-keygen -t rsa -b 4096 -C "your_email@example.com" 的时候没有加-b 4096后面运行ssh-add ~/.ssh/id_rsa就报错了:Could not open a connection to your authentication agent,解决办法,

 eval `ssh-agent -s` 

再次执行ssh-add ~/.ssh/id_rsa就好了

运行ssh -T git@gitee.com返回
Hi assassin! You've successfully authenticated, but Gitee.com does not provide shell access.
表明链接成功,但是我还是没法通过ssh的方式clone代码,会报错:
git@gitee.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
一头雾水,应该是我多账号的问题,我的电脑有公司的,有自己的,所以git无法识别,Windows下Git多账号配置,同一电脑多个ssh-key的管理需要在.ssh目录下新建一个config文件

# 配置gitee.com
Host gitee.com 
    HostName gitee.com
    IdentityFile C:\\Users\\lenovo\\.ssh\\gitee_rsa
    PreferredAuthentications publickey
    User username2

这样就可以通过ssh clone代码了

gitee码云使用webhook自动部署前端代码就用到了公钥

15. 版本回退

  • 已push的代码最好使用revert
  • 已commit未push的代码使用reset
    对于已经commit但没push的代码的回退往往就需要reset进行操作
    reset中三种方式的区别mixed soft hard
    git reset 三种用法总结
  • 已add到暂存区的代码回到工作区
    use "git reset HEAD <file>..." to unstage
    同样使用reset
  • 撤销工作区的代码
    1.对于修改的文件use "git checkout -- <file>..." to discard changes in working directory
    2.对于新增的文件rm filename
    git放弃修改&放弃增加文件用了git clean -xdf发现新的的文件从工作区删了,同时也把node_modules目录删了
git reset revert 回退回滚取消提交返回上一版本
Git恢复之前版本的两种方法reset、revert
git 优雅的撤销中间某次提交

16. git不区分大小写

开始文件名叫AddUser.js,我在Windows上把文件名改成addUser.js然后push到远端,远端仓库显示还是AddUser.js,原来是git默认对文件大小写也不区分,然后设置git config core.ignorecase false,push到远端,远端居然有两个文件AddUser.js和addUser.js都在,没这让人火大,使出第二招git rm AddUser.js发现两个都被删了,最后只好再次添加addUser.js,这时候只是把AddUser.js删了,然后push就没问题了

git 默认对文件名大小写不敏感 (不区分文件名大小写)

17. github 切换https到ssh

git remote set-url origin git@github.com:xxx/xxxx.git

git remote -v // 查看远程仓库地址

github项目切换远程https到ssh通道

18. 已push的文件 .gitignore不起作用

git rm -r --cached .
git add .
git commit -m 'update .gitignore'

Git中.gitignore文件不起作用的解决以及Git中的忽略规则介绍

19. 在已有的分支上拉去远端代码 (pull fetch 的区别)

  1. 本地与远端建立关系后,最便捷的方式是git pull直接拉去远端到本地,如果本地和远端分支没有建立关系,可以使用git pull origin master使用origin制定远端分支
  2. 使用fetch 和 merge
  • 对于本地已存在的分支master

git fetch origin master
//代码拉去到了本地,但没有合并到master分支

git merge origin/master
//把刚才从远端拉取到的新代码合并到本地master分支,如果不先fetch,执行 git merge origin/master是没发把远端新的代码合并到master分支的

本地已存在的分支master,如果直接使用git fetch origin master:master,会报错 fatal: Refusing to fetch into current branch refs/heads/master of non-bare repository

综上git pull 相当于git fetch + git merge

  • 对于本地不存在分支master

fetch pull 区别

git fetch & git pull
Git fetch & pull 详解

20. 先merge 再revert到merge之前的代码

Git如何回滚一次错误的合并
当你决定去 revert 一个merge commit
Git怎样撤销一次分支的合并Merge

今天的操作是 先merge master分支的代码到发现有冲突 然后解决冲突,push到直接的分支 然后发个pull request然后manager merge了pull request到master,这个时候发现代码本地分支代码还有冲突,其实这个时候可以git reset ,但是如果有人在manager 合并了我的pull request后,提交了新的代码到master,那么reset会造成别人的代码会丢失,所以这个时候只能用revert

master 有reset操作 我bill分支merge了master分支的代码,但是在我merge master分支之前写了一些代码,在merge的时候git会自动将master代码混入到我的分支,这个时候我想保留我本地的代码,但是又害怕别人在后面有新的代码push到master,如果用reset可能将别人新push的代码去掉,所以用revert操作,

  1. 使用git revert [merge前一条commit id] 会将自己分支写的代丢失掉
  2. 使用git revert -m 1 [merge 的那一条commit id]这个时候会回退到merge之前自己分支的代码

21. git commit -a -m "提交信息"

对于被tracked文件可以不用git add . 直接这么提交

但是对于新建的文件必须先git add .然后commit

git第一次提交不能使用git commit -a -m

22. git mv -f abc.vue Abc.vue 解决大小写不敏感问题

git 不区分文件名大小写, 无法检测到差异, 导致文件内容的差异push成功

23. 工作区 暂存区 历史记录区之间的操作

  • 工作区到暂存区 git add text.md或者git stage text.md

其实,他们两是同义的,所以,惊不惊喜,意不意外?这个问题竟然是个陷阱…引入 git stage 的原因其实比较有趣:是因为要跟 svn add 区分,两者的功能是完全不一样的,svn add 是将某个文件加入版本控制,而 git add 则是把某个文件加入暂存区,因为在 git 出来之前大家用 svn 比较多,所以为了避免误导,git 引入了git stage,然后把 git diff --staged 做为 git diff --cached 的相同命令。基于这个原因,我们建议使用 git stage 以及 git diff --staged。
来自面试中的那些 Git 问题 - 基础部分

  • 暂存区撤销到工作区 单个文件/文件夹 :git reset HEAD text.md , 所有文件/文件夹:git reset HEAD .
  • 撤销工作区文件的修改(对于已被git追踪的文件)git checkout -- text.md
  • 撤销新增到工作区的文件 单个文件/文件夹::rm filename / rm -rf dir, 所有文件/文件夹:git clean -xdf
    git reset放弃修改&放弃增加文件指出可以使用git clean -xdf,但是执行了发现不但新增的文件被删除了,而且node_modules目录也被删了,所以慎用

24. git pull origin master & git pull origin/master 还是有区别的

Differences between git pull origin master & git pull origin/master

25. 拉取别人的github pull request 到本地

有的pr的内容比较多,需要验证其实现的功能有没有work,则需要拉取远程的pr到本地,比如 git fetch upstream pull/1107/head:pr1107然后再去切换分支查看就好了。

  • 如果在我创建好改pr分支后,贡献者又push了代码到该pr,我该怎样获取最新的代码?
    执行 git pull upstream pull/1107/head
  • 又遇到了问题,别人提了pr我想验证他的功能是不是好的,我用上述方式将代码fetch到本地,但是我发现他的代码不是最新的,导致一些功能是坏的,查看github的差异比对,如下图
    image.png
    这里的差异只显示了贡献者修改的代码,并没有显示出他的分支跟我们的main分支的其他差异,而我fetch到本地的代显示出了两个分支的所有差异,这是什么原因?难道是git有bug?于是去查看贡献者的仓库
    image.png
    他的分支落后了253个commit,原来是由于贡献者没有同步仓库最新代码导致的问题,该怎么解决呢?
    经过跟同事的讨论,他给了我解决办法:

    git fetch upstream pull/3568/merge:merge3568

    这样拉到本地的pr就是贡献者和主仓库的最新代码了。

参考:
Git拉取pull request到本地命令

26. 找回 git pull --force 掉的代码

提交前拉取新代码

  • git commit 代码
  • git pull --force upstream main

经过上述两步操作后发现本地的提交没了,该如何是好?
同时给出了两条路:

  • git reflog
  • git fsck --full查看dangling commit

首先使用reflog,找到了被干掉的那commit,然后使用 git cherry-pick 4e2b6a0b 将该条commit就找回来了。
image.png

但是使用git fsck --full并没有发现我被冲掉的那条记录,有待考证。
git reset --hard 需要保留的修改没了怎么办?git fsck --lost-found
git fsck --lost-found命令用法
参考上述两篇可知fsck可以将没有add的代码找回,有待进一步验证。


assassin_cike
1.3k 声望74 粉丝

生活不是得过且过