git相关
在客户环境里用git时遇到一个很讨厌的事情。既之前设置的git账号的密码变了,当然这个改变是因为客户IT每隔一段时间就会修改密码。
事情原尾是这样的:
我们用uipath开发RPA流程,在客户虚拟机上运行。 UiPath自带版本管理工具,支持git和TFS等。 我们为了方便集中管理多个流程,就让用户建了一个仓库,把所有流程都放在这个仓库里,以不同的文件夹区分开。
后期我们使用时经常遇到各种问题(在uipath界面中操作):
- 明明只想提交对一个流程的修改,但其他流程跟着一块提交了。
- 本想undo一个流程,但总是undo不干净,点击undo之后总是还会提示期望undo的文件没有被undo。
一时想不全,感觉就是问题一大堆。 于是打算用git命令行自己来控制文件的提交。 但命令行直接git pull,提示authentication failed。 明明uipath界面里的账号和密码是对的,但是命令行里不知道保存的何时的密码,也不知道保存在了哪里。
对着chatGPT一通问,中间不知反复尝试了多少种命令。 总之,就是手工把凭据管理器里的凭据删掉了。 希望在命令行里使用git pull命令时会弹出输入账号密码的弹窗,但就是不弹,只提示authentication failed。
最后有效的解决步骤如下:
依次执行了下述命令
git config --system --unset credential.helper
git config --global --unset credential.helper
git config --local --unset credential.helper
git config --global credential.interactive always
git pull
在命令行里提示输入用户名和密码。
输入后,命令执行成功。 但是因为目前设置的是每次git pull或git push这种命令都需要输入用户名和密码,于是再执行下面命令
git config --global credential.helper store (注意,这种方法存储用户名密码是以明文存储,不借助windows凭据管理器,但简单有效。)
git config --global --unset credential.interactive
中间还记着用过git credential fill | approve | rejct等命令,不知道干啥用,也不知道起没起作用。
总之,git 在windows上总是感觉有莫名奇妙的问题,很恶心。
客户环境更恶心,首先没有管理员权限,有些东西设置不了,也不能安装东西。 其次,不能访问外网,查个百度都不能。 最后,东西进不去出不来,完全与世隔绝。 最最重点的是,机器慢的要死,卡的要死。 vpn连他们环境还总掉线,垃圾的一批。
查看本地仓库关联的无端库信息:
git remote -v
查看所有本地及远端分支:
git branch -a
当我做了些修改,但我想还原这些操作
git restore .
但是当我添加了一些文件,并且这些文件没有使用git add . 命令添加到暂存区,同时这些文件也从未被跟踪过,我想移除这些文件
git clean -f
但是如果同时也想删除未被跟踪的目录则要用下面的命令
git clean -fd
如果我想还原的文件已经被我添加到了暂存区,即git add .命令添加的。那么我要执行下面两个命令才能还原。
git reset 将暂存区的内容移除
git restore . 将未被添加到暂存区的改动进行还原。
当我有已跟踪的文件发生了改变,我想直接提交,可以这样
git commit -a -m "messge"
它相当于执行了 git add . 加上 git commit -m "message" 这两条命令。
但是如果我有新增的文件(从未被跟踪过),并且其没有添加到暂存区, 这时使用**git commit -a -m "message" **命令并不能将其提交到仓库,而是得顺序执行下面两条命令
git add .
git commit -m "message"
当我想查看都哪些文件被跟踪了,其实就是当前仓库里已经提交过的文件
git ls-files
当想将本地仓库关联到远端仓库里
git remote add origin https://gitee.com/xxxxx.git
git push -u origin "master" 在推送的同时绑定远端库的分支。 使用一次 -u,就代表永久绑定,后续就可以直接使用git push了
如果在公司电脑上遇到如下问题时:
fatal: unable to access 'https://gitee.com/xxxxx.git/': SSL certificate problem: unable to get local issuer certificate
切换成ssh的方式:
git remote set-url origin git@gitee.com:xxxxx.git
再重新push就可以了。 但前提是先在公司电脑上生成ssh key并配置到git远端仓库服务器里。
在git命令行里,显示的文件名里的中文是unicode转义字符,如何显示成中文。
以在windows系统中使用windows terminal,并且标签显示Windows Powershell。使用如下命令:
# 1. 确保 Git 不转义路径
**git config --global core.quotepath false**
# 2. 在 PowerShell 配置文件中添加(永久生效)
**[Console]::OutputEncoding = [System.Text.Encoding]::UTF8**
gitignore文件介绍
总结:
git仓库里可以在不同层级目录里存在.gitignore文件。仓库中的文件同时受不同层级的.gitignore文件的影响,但离文件越近的.gitignore文件的优先级越高。
.gitignore 文件只对未跟踪的文件生效。如果文件已经被 Git 跟踪,需要先用 git rm --cached
模式前面不加"/"的,代表匹配所有层级目录,加"/"的,表示从根目录还始匹配。(注意,这里的根目录指的是.gitignore文件所在的目录)。简写的路径模式可以省略前面的"/"。例如foo/bar等价于/foo/bar
模式后面加"/"的,只匹配目录,不匹配文件。 模式后面不加"/"的,可以同时匹配文件和目录。
"*"为通配符。foo不能匹配foo.txt,可以通过foo.*来匹配所有文件名为foo,不考虑扩展名的文件。
"**"为多层级匹配符。 **/foo 等价于 foo, 因为git对单层模式默认递归匹配。 **/foo/bar 不等价于 foo/bar。 对于路径模式默认不做递归匹配,因此foo/bar只能匹配根目录下的foo文件夹里的bar。
以"/**"结尾时,代表匹配目录下的所有内容。比如 foo/**,代表匹配foo目录里所有内容,其实等价于 foo/
**注意**: foo/ 是单层模式,代表foo文件夹。(不是带/就是路径模式) 。而foo/bar则是路径模式,匹配根目录下的bar
foo :可以匹配foo文件名,foo文件夹,但不能匹配foo.txt, foo.log等。
foo.* :可以匹配foo.txt, foo.log等,但不能匹配foo文件名,foo文件夹
foo* : 可以匹配foo.txt, foo.log等,同时也能匹配foo文件名,foo文件夹名, 还能匹配footest文件名或文件夹,footest.txt, footest.log等文件名
foo/ :可以匹配foo文件夹,但不能匹配foo文件名
foo*/ : 可以匹配foo文件夹,但不能匹配foo文件名。 可以匹配footest文件夹,但不能匹配footest文件名,以及footest.txt, footest.log等文件名
*foo : 可以匹配abcfoo文件夹或文件名,foo文件夹或文件名, 但不能匹配abcfoo.txt, abcfoo.log等文件名
!testfoo : 否定规则。 不匹配testfoo。
git默认主分支
git社区从2020年开始就将主分支由原先的master改为main了,但windows安装的git默认还沿用master这个旧的名称。
可以使用下面命令配置全局设置,下次在使用git创建仓库时主分支就是main了。
# 立即执行,让您的 Git 跟上时代
git config --global init.defaultBranch main
# 可以将本地分支改名字 git branch -m <原分支名> <新分支名>
git branch -m master main
# 当我们无意间把本地master分支推送到远端,并在远端创建了同名的master分支后,我们最好将远端的master分支删掉。
git push origin-gitlab --delete mastet
# 上面可以删除远端分支的前提是 要删除的分支不能是远端库的默认分支。
git remote show origin # 这个命令可以用于查看远端库的默认分支
# 如果远端库的默认分支就是master,则不能删除它。这个时候需要登录远端仓库,手工更改默认分支为main,然后再删除。
将本地分支与上游(远端仓库)分支绑定
# 完整的分支绑定或者说追踪语法
git branch --set-upstream-to=<remote>/<remote-branch> <local-branch>
# 举例:把本地master分支的上游设置为远端的main分支
git branch --set-upstream-to=origin-lab/main master
# 如果不指定本地分支名,则默认将本地的当前分支绑定到上游分支
# 举例,假设本地当前分支是master,下面命令将把master分支绑定到远端库main分支。
git branch --set-upstream-to=origin-lab/main
# 下面这种方式可以在推送的同时设置上游分支
git push -u origin master:main
git push的完整语法
git push <remote> <当前分支>:<上游分支>
# 举例:将本地master分支推送到远端main分支
git push origin master:main
# 用HEAD来代表本地当前发支
git push origin HEAD:main
# 当要推送的本地分支和远端分支同名时,可以简写
git push origin master # 本地的master分支推送到远端master分支
# 当本地当前分支与远端分支已经绑定,但本地仓库添加了多个远端库时,需要指定远端库名
git push origin-gitlab # 假设远端库叫origin-gitlab
# 当本地当前分支与远端分支已经绑定,并推送本地当前分支,可以简写。但前提条件是,本地分支绑定的远端分支必须同名,这个条件是git config里的默认配置push.default=simple
git push # 这种也是我们一般情况下使用的方式
git pull的完整语法
git pull <远程名> <分支名>
# 举例: 将远端库origin的main分支合并到本地仓库的当前分支。注意,这个命令不能指定本地分支,而只是本地当前分支。这种情况下,本地分支和上游分支可以不同名,并且本地当前分支可以是未绑定到远端分支的状态。
git pull origin main
git pull <远程名>
# 举例: 将与本地当前分支同名的远端分支合并到本地当前分支,前提是本地当前分支已经绑定到了远端同名分支。
git pull origin
git pull
# 举例: 若本地仓库只添加了一个远端库,并且本地当前分支已经绑定到了远端同名的上游分支,则可以简写成 git pull。 这其实也是最常用的场景。
git配置文件的三层分级结构
Git 的配置系统采用三层分级结构,每一层对应不同的作用范围和优先级。这种设计使得 Git 既灵活又安全,既能满足全局默认设置,又能为单个项目定制特殊行为。
## 📁 第一层:本地层(Local)——`.git/config`
### 📍 路径:
```bash
<你的项目目录>/.git/config
🎯 作用范围:
- 仅对当前 Git 仓库生效
- 每个仓库都有自己的
.git/config
✅ 常见配置项:
[core]
repositoryformatversion = 0
filemode = true
bare = false
[remote "origin"]
url = https://gitee.com/user/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
🔧 如何设置?
git config branch.main.remote origin
默认操作的就是本地层(不加
--local也默认为此层)
🚫 注意:
- 该文件不会被提交到远程仓库
- 换一台机器
git clone后,此配置不会自动继承
🌍 第二层:全局层(Global)——~/.gitconfig
📍 路径:
- Linux/macOS:
~/.gitconfig或~/.config/git/config - Windows:
C:\Users\<用户名>\.gitconfig
⚠️
~表示用户主目录
🎯 作用范围:
- 对当前用户的所有 Git 仓库生效
✅ 常见配置项:
[user]
name = Your Name
email = your.email@example.com
[core]
editor = vim
autocrlf = input
[color]
ui = auto
[alias]
co = checkout
br = branch
st = status
last = log -1 HEAD
🔧 如何设置?
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
git config --global core.editor "code --wait"
✅ 推荐设置:
user.name和user.email:每次提交都会记录alias:自定义快捷命令pull.rebase:设置git pull使用 rebase 而非 merge
🖥️ 第三层:系统层(System)——/etc/gitconfig
📍 路径:
- Linux:
/etc/gitconfig - macOS:
/usr/local/etc/gitconfig或/etc/gitconfig - Windows: 通常在 Git 安装目录,如
C:\Program Files\Git\etc\gitconfig
🎯 作用范围:
- 对系统上所有用户、所有仓库生效
✅ 常见用途:
- 企业或组织统一设置默认编辑器、换行符处理等
- 设置代理、安全策略等
🔧 如何设置?
# 需要管理员权限
sudo git config --system core.editor "vim"
sudo git config --system init.defaultBranch main
⚠️ 注意:
- 普通用户通常没有权限修改此文件
- 修改会影响所有用户,需谨慎
🔍 如何查看各层配置?
1. 查看所有生效配置(合并后)
git config --list
2. 查看某一配置的最终值
git config user.name
3. 查看某一层的配置
| 命令 | 说明 |
|---|---|
git config --local --list |
查看本地层 |
git config --global --list |
查看全局层 |
git config --system --list |
查看系统层 |
git config --show-origin --list |
显示配置值及其来源文件 |
✅ 推荐使用最后一个命令,它能清晰告诉你每个配置来自哪个文件:
git config --show-origin --list
输出示例:
file:/home/user/.gitconfig user.name=Your Name
file:/home/user/.gitconfig user.email=you@example.com
file:.git/config branch.main.remote=origin
file:/etc/gitconfig init.defaultBranch=main
🎯 各层配置的典型使用场景
| 配置项 | 建议设置层级 | 说明 |
|---|---|---|
user.name / user.email |
--global |
个人身份信息 |
core.editor |
--global |
个人偏好 |
alias.* |
--global |
个人快捷命令 |
pull.rebase |
--global |
统一合并策略 |
branch.<name>.remote |
--local |
项目特定的远程绑定 |
remote.pushdefault |
--global 或 --local |
根据场景选择 |
init.defaultBranch |
--system 或 --global |
组织规范 |
✅ 实际案例:从 master 到 main 的迁移
# 系统层(管理员设置组织规范)
git config --system init.defaultBranch main
# 全局层(您个人设置)
git config --global init.defaultBranch main
# 本地层(某个项目特殊需求,比如必须用 master)
cd old-project
git config init.defaultBranch master
此时:
- 新项目默认创建
main分支 old-project仍使用master
✅ 总结
| 层级 | 文件 | 作用范围 | 优先级 | 推荐用途 |
|---|---|---|---|---|
| 本地(Local) | .git/config |
当前仓库 | ⭐⭐⭐ 高 | 项目特定配置 |
| 全局(Global) | ~/.gitconfig |
当前用户所有仓库 | ⭐⭐ 中 | 个人偏好、身份信息 |
| 系统(System) | /etc/gitconfig |
所有用户所有仓库 | ⭐ 低 | 组织统一策略 |
💡 口诀:
- 个人设置用
--global- 项目特殊用
--local(默认)- 统一规范用
--system
即:如果同一配置在多层中出现,优先使用优先级高的层的值。
git的三区思想
Git 实际上维护三个主要状态(常被称为“三棵树”):
| 名称 | 说明 |
|---|---|
| 1. HEAD | 上一次提交的快照(即当前分支的最新 commit) |
| 2. Index / Staging Area(暂存区) | 下一次 commit 将要包含的内容(是 HEAD 的“修改版”) |
| 3. Working Directory(工作区) | 你磁盘上实际看到的文件 |
Index 到底存了什么?
Index(.git/index)是一个二进制文件,它保存的是:
- 一组文件路径
- 每个文件对应的 blob 对象 ID(即内容的 SHA-1 哈希)
- 文件元数据(如权限)
✅ 所以 Index 本质上是一个 “文件名 → 内容快照” 的映射表。
当你执行以下命令时,手动或半自动地更新了 Index:
git add
git rm
git rm --cached
git add -u → 自动 add 所有已跟踪文件的修改和删除
git add . → add 所有新文件 + 修改(但不包括删除)
你完全可以做到在工作区中(你能看得到的文件)修改任何文件,并且不把它add到暂存区(Index/Staging Area), 这样你对这个文件的更改(包括新增文件)就不会被提交。
💡 git status 的作用就是对比三者:
工作区 vs Index → 显示“未暂存的更改”
Index vs HEAD → 显示“已暂存的更改”
在英文表述里,工作区中的文件发生了更改,或新增,或者从已提交的文件列表中删除,等等这些情况,在没有被添加到暂存区时,就称为unstaged状态,如果已被添加到暂存区,则被称为staged状态。staged状态的内容就是提交时会更新到仓库中的内容。

浙公网安备 33010602011771号