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,但保留之前的修改
别人的方法,尝试了没效果:
- 找到上次Git commit的 id
git log
找到你想撤销的commit_id
2. git reset --hard commit_id
完成撤销,同时将代码恢复到前一commit_id 对应的版本。 - 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的区别
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文件
类似于下面
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 并不起作用,那么怎么办呢?原来暂存分为两种情况:
- 文件已经被 git 跟踪,只是修改了代码(而不是新条件文件),我们可以使用 git stash 或 git stash save "注释" 来暂存修改。
- 如果有新添加的文件,那么就需要添加 -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
就行了。
同理可以切换代码到历史某次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 ""
11. git 修改已提交的内容
12. git rebase develop
- 在master下新建index.html文件
- git checkout -b develop 新建文件file.txt
3.切回master 再新建bill分支 新建logo.txt 执行 git rebase develop
- 切回master 再新建assassin分支 新建geek.txt 执行 git merge develop
对比两图可以发现,在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 -igit 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.为项目添加公私钥
由于运行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 // 查看远程仓库地址
18. 已push的文件 .gitignore不起作用
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
Git中.gitignore文件不起作用的解决以及Git中的忽略规则介绍
19. 在已有的分支上拉去远端代码 (pull fetch 的区别)
- 本地与远端建立关系后,最便捷的方式是
git pull
直接拉去远端到本地,如果本地和远端分支没有建立关系,可以使用git pull origin master
使用origin制定远端分支 - 使用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
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操作,
- 使用
git revert [merge前一条commit id]
会将自己分支写的代丢失掉 - 使用
git revert -m 1 [merge 的那一条commit id]
这个时候会回退到merge之前自己分支的代码
21. git commit -a -m "提交信息"
对于被tracked文件可以不用git add . 直接这么提交
但是对于新建的文件必须先git add .
然后commit
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的差异比对,如下图
这里的差异只显示了贡献者修改的代码,并没有显示出他的分支跟我们的main分支的其他差异,而我fetch到本地的代显示出了两个分支的所有差异,这是什么原因?难道是git有bug?于是去查看贡献者的仓库
他的分支落后了253个commit,原来是由于贡献者没有同步仓库最新代码导致的问题,该怎么解决呢?
经过跟同事的讨论,他给了我解决办法:git fetch upstream pull/3568/merge:merge3568
这样拉到本地的pr就是贡献者和主仓库的最新代码了。
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就找回来了。
但是使用git fsck --full
并没有发现我被冲掉的那条记录,有待考证。
git reset --hard 需要保留的修改没了怎么办?git fsck --lost-found
git fsck --lost-found命令用法
参考上述两篇可知fsck可以将没有add的代码找回,有待进一步验证。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。