Post

Git常用命令与常见问题记录

Git常用命令与常见问题记录

常用命令

  • push

  • pull

  • add

  • rm

  • switch

  • branch

  • fetch

  • merge

  • rebase

  • cherry-pick

  • diff

  • commit

  • reset

  • log

  • reflog

    • git log是显示当前的HEAD和它的祖先的,递归是沿着当前指针的父亲,父亲的父亲,…,这样的原则。

    • git reflog根本不遍历HEAD的祖先。它是HEAD所指向的一个顺序的提交列表:它的undo历史。reflog并不是repo(仓库)的一部分,它单独存储,而且不包含在pushes,fetches或者clones里面,它纯属是本地的。

    • reflog可以很好地帮助你恢复你误操作的数据,例如你错误地reset了一个旧的提交,或者rebase,…,这个时候你可以使用reflog去查看在误操作之前的信息,并且使用git reset –hard 去恢复之前的状态。

    • 但当你进行 git checkout -- <filename>撤销或者 git stash存储文件等操作时,EAD 并不会改变,这些修改从来没有被提交过,因此 reflog 也无法帮助我们恢复它们

config环境

主动设置git用户

1
2
git config --global user.name "jelech"
git config --global user.email "jelech@hotmail.com"

国内经常遇到的proxy问题

1
2
3
4
5
6
# 设定代理
git config --global https.proxy http://127.0.0.1:1080
git config --global https.proxy https://127.0.0.1:1080
# 取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy

常见问题

拉取别人的远程分支合并后,git 会存取这个拉取的记录,如果你不小心删了别人的上传的文件,这时候想要再拉取别人的分支是没用的,会显示 already-up

这时候可以回滚代码,重新拉取。

以前有过这样的经历:前后端、客户端的代码都存放在一个 git 仓库中,在根目录下各自新建项目目录。那么可以直接在自己的项目目录下使用 git 提交代码并且在各自的项目目录下配置 .gitignore 文件,不用在根目录下配置 .gitignore 文件,这样就互不影响了。

fatal:refusing to merge unrelated histories 拒绝合并不相关的历史

在 git 2.9.2 之后,不可以合并没有相同结点的分支(分支之间自仓库建立后,从来没有过互相拉取合并)。如果需要合并两个不同结点的分支,如下:

1
2
git pull origin branchName --allow-unrelated-histories
git merge branchName --allow-unrelated-histories

这个功能是可以让大家不要把仓库上传错了,如果会加上这个代码,那么就是自己确定了上传。旧版本的 Git 很容易就把代码传错了,现在可以看到,如果上传的不是之前的,那么就需要加代码上传。正常情况下,都是先建立仓库,然后切多个分支,分支先去拉取合并主分支的内容,然后再各自开发, 如果建立仓库后,各个分支没有区拉取主分支的代码,之后各个分支之间想要合并时就会报错。

合并分支时出现问题,想要解除合并状态

1
error: merge is not possible because you have unmerged files.hint: Fix them up in the work tree, and then use 'git add/rm <file>'hint: as appropriate to mark resolution and make a commit.fatal: Exiting because of an unresolved conflict.

当远程分支和本地分支发生冲突后,git 保持合并状态,你如果没有去解决完所有的冲突,那么 git 会一直保持这个状态,你就无法再提交代码。只有先解除合并状态后,才能继续提交。执行命令前最好先备份一下,有可能本地做的修改会被远程分支覆盖掉。

1
2
# 解除合并状态
git merge --abort

不小心把某些文件上传到远程 git 仓库/想要删除远程仓库中的文件

1
2
3
# 删除暂存区和工作区的文件
git rm filename# 只删除暂存区的文件,不会删除工作区的文件
git rm --cached filename

如果在配置 .gitignore 文件之前就把某个文件上传到远程仓库了,这时候想把远程仓库中的该文件删除,此时你配置 .gitignore 文件也没有用,因为该文件已经被追踪了,但又不想在本地删除该文件后再重新提交到远程仓库,这时候可以使用 git rm --cached filename 命令取消该文件的追踪,这样下次提交的时候,git 就不会再提交这个文件,从而远程仓库的该文件也会被删除

将本地新建的项目上传到新建的远程仓库上

之前没有进行过关联,即没有通过 clone 远程项目到本地再开始做项目,而是先本地新建了一个项目,然后想传到远程仓库上。

1
2
3
4
5
6
# 将本地仓库和远程仓库关联起来
$ git remote add origin 远程仓库地址
# 将本地的 master 分支推送到 origin 主机,同时指定 origin 为默认主机
git push -u origin master
# 上面的命名执行后,下次再从本地库上传内容的时候只需下面这样就可以了
git push

每次 git push 都要输入用户名、密码

  • step 1:生成公钥
1
2
ssh-keygen -t rsa -C "xxxxx@xxxxx.com"# Generating public/private rsa key pair...
# 三次回车即可生成 ssh key
  • step 2:查看已生成的公钥
1
cat ~/.ssh/id_rsa.pub
  • step3:复制已生成的公钥添加到 git 服务器

测试 ssh 是否能够连接成功

1
ssh -T git@github.com
  • step4:使用 ssh 协议 clone 远程仓库 或者 如果已经用 https 协议 clone 到本地了,那么就重新设置远程仓库

「使用 ssh 协议」

1
git remote set-url origin git@xxx.com:xxx/xxx.git
  • step5:创建文件存储用户名和密码

一般为 C:\users\Administrator,也可以是你自己创建的系统用户名目录,文件名为 .git-credentials。由于在 Windows 中不允许直接创建以 “.” 开头的文件,所以用命令行创建该文件。

```plain text touch .git-credentials echo “http://{username}:{password}@github.com” » ~/.git-credentials git config –global credential.helper store

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
### **git 不允许提交空文件夹**

可以在当前目录下,添加一个 .gitkeep 文件

### **Another git process seems to be running in this repository, e.g.**

![](https://segmentfault.com/img/remote/1460000023734715)

原因在于 Git 在使用过程中遭遇了奔溃,部分被上锁资源没有被释放导致的。

**「解决方案:」** 进入项目文件夹下的 .git 文件中(显示隐藏文件夹或 `rm .git/index.lock`)删除 index.lock 文件即可。

### **git commit -am "xxx" 有时候会失效,无法提交所有的修改**

`git commit -am "xxx"` 只会将被 **「tracked」** 的文件添加到暂存区并提交,而将文件添加到 git 管理是要使用 git add 命令,将新的文件 **「tracked」** 。(新建了文件之后,idea 会提示你是否需要加到 git 管理中。选择记住后,之后 idea 默认都会把新建的文件 **「tracked」** 化)

### **git merge --no-ff 的作用**

*   **「禁止快进式(fast-forward)合并,会生成一个新的提交」**

![](https://segmentfault.com/img/remote/1460000023734716)

从合并后的代码来看,结果都是一样的,区别就在于 `--no-ff` 会让 git 生成一个新的提交对象。为什么要这样?通常我们把 master 作为主分支,上面存放的都是比较稳定的代码,提交频率也很低,而 feature 是用来开发特性的,上面会存在许多零碎的提交,快进式合并会把 feature 的提交历史混入到 master 中,搅乱 master 的提交历史。所以如果你根本不在意提交历史,也不爱管 master 干不干净,那么 `--no-ff` 其实没什么用。

### **git log 无法正常显示中文**

```shell
# 试试
git -c core.pager=more log
# 如果可以显示中文的话,把 pager 设置为 more
git config --global core.pager more

git merge -m “xxx” 的时候可以附加信息

  • 默认是 Merge branch branchName

git pull 会拉取所有远程分支的代码到本地镜像仓库中

想要 merge 别人的分支时:

  • 如果你的本地仓库中已经有了他人的分支(直接切换到他人分支,就会在本地生成一条他人的分支),就可以使用 merge branchname;

  • 如果你的本地仓库没有他人的分支,那么就得使用 merge origin/branchname 来合并

git stash 存储未追踪的文件

  • 如果我们新建了文件,但是没有用 git add . 追踪文件,那么 git stash 是无法存储的
1
git stash -u

git push 无法提交代码

「可能出现的报错:」

  • 「remote:」 Permission to xxxxx.git denied to xxx. fatal: unable to access ‘github.com/ xxxxx.git/’: The requested URL returned error: 403

  • 「remote:」 You do not have permission to push to the repository via HTTPS

    「fatal:」 Authentication failed for ‘gitee.com/xxx.git/’

1
2
# 查看当前项目的 git 配置
cat .git/config
  • 查看本地项目的 .git/config 设置的仓库 url 地址和 github 使用的链接地址是否一致。git push 的数据协议有两种方式:ssh 和 https。如果不一致就需要切换 url 地址。

git 输错用户名和密码,后续的 git 操作一直报错

1
remote: Coding 提示: Authentication failed.remote: 认证失败,请确认您输入了正确的账号密码。fatal: Authentication failed for 'https://e.coding.net/xxx.git/'

在控制面板里找到凭据管理器,选中 Windows 凭据,找到 git 的凭据,点击编辑,输入所用 github 的正确用户名和密码。

lint-staged 失败

可能你的项目名路径中包含了中文名,需要替换成英文名

查看 git 安装目录

  • 「Mac:」 在命令行中输入 which git,就会显示 git 的安装位置了

  • 「Windows:」 打开cmd,输入 where git,就会显示 git 的安装路径了

如何修改旧的 commit 的 message/如何将多个 commit 合成一个 commit/如何将多个间隔的 commit 合成一个 commit/

1
git rebase -i

如果两个人都对某个文件进行了修改,一个是重命名文件,一个是修改文件内容,那么会起冲突吗?

  • git 很智能,会自动合并这些修改

  • 如果两个人都对同一个文件重命名,此时会起冲突,git 不会自动处理,需要开发者自身去解决冲突

git revert 失败:error: Commit faulty merge is a merge but no -m option was given、error: option `mainline’ expects a number greater than zero

1
git revert -m 1

git 创建一个空的分支

在 Git 中创建分支,是必须有一个父节点的,也就是说必须在已有的分支上来创建新的分支,如果工程已经进行了一段时间,这个时候是无法创建空分支的。但是有时候就是需要创建一个空白的分支。

1
git checkout --orphan emptyBranchName

该命令会生成一个叫 emptybranch 的分支,该分支会包含父分支的所有文件。但新的分支不会指向任何以前的提交,就是它没有历史,如果你提交当前内容,那么这次提交就是这个分支的首次提交。

想要空分支,所以需要把当前内容全部删除,用 git 命令

1
git rm -rf . // 注意:最后的‘.’不能少。

如何清空一个分支的所有提交

先删除该分支,然后再新建一个空的分支(分支名就是删除的分支名)

This post is licensed under CC BY 4.0 by the author.