Git使用方法
如何使用Git
安装
...
初始化
设定用户名
git config --global user.name "用户名"
设定邮箱
git config --global user.email "邮箱@email.com"
保存用户名和密码
git config --global credential.helper store
查看设定
git config --global --list
删除某项设定
git config --global unset user.email
新建仓库/目录/repo
创建
在当前目录创建仓库
git init
当前文件夹下创建一个新的目录作为仓库
git init <repoName>
抄袭一个仓库
git clone https://github/usernmae/reponame.git
工作区域和文件状态
工作区域
文件状态
查看暂存区中的文件
git ls-files
添加和提交文件
查看当前仓库状态
git status
简单回显:
git status -s
添加追踪文件
git add <file-name>
或者使用通配符添加
git add .
提交文件
仅添加暂存区文件,不添加未跟踪文件
git commit
撤销/回退
soft
回退到某版本并保存工作区和暂存区的所有内容
git reset --soft <版本id>
hard
git reset --hard <版本id>
回退到某版本,丢弃工作区和缓存区的内容
mixed
git reset --mixed <版本id>
回退到某版本,仅保留工作区内容,不保留缓存区内容
对比文件差异内容
查看工作区、暂存区之间的差异
git diff
查看工作区和版本库的差异
git diff --cached
比较任意两个版本之间的差异
-
直接指定两个版本
git diff <版本id> <版本id>
-
或使用
HEAD
代表当前版本与某一个版本的比较差异git diff HEAD <版本id>
-
或使用
HEAD
代表当前版本与上一个版本的比较差异git diff HEAD~ HEAD
- 其中
~
可以替换为^
。
- 其中
-
或使用
HEAD
代表当前版本与之前某一个版本的差异git diff HEAD^2 <版本id>
- 其中的数字n表示前面n个版本
-
比较某两个版本之间某个文件的差异内容
git diff <id> <id> filename
-
比较两个分支的差别
git diff <分支名> <分支名>
删除暂存区中某个文件
-
方法一
操作系统删除当前工作区的文件
- 重新进行
git add .
- 重新进行
-
方法二:
git rm filename
可以递归删除某个目录
git rm -r *
或者仅仅在暂存区中删除,工作目录保留
git rm --cached <filename>
**注意:**版本库中仍然存在这个文件,需要重新进行git commit
gitignore
忽略掉一些不需要加入到版本库中的文件
在gitignore
文件中写入不需要版本控制的文件的文件名:
output.log
这样output.log文件就不会被同步了
或者使用通配符:
*.log
忽略所有以.log
结尾的文件
**注意:**如果之前手动加入了某个被忽略规则适配的文件,则其修改仍然会被git检测。从暂存区中删除后则不会被追踪。
忽略文件夹:
temp/
匹配规则:
gitignore
文件指定了 Git 追踪时应忽略的文件。 已被 Git 追踪的文件不受影响,详见下面的注释。
gitignore
文件中的每一行都指定了一个模式。 在决定是否忽略路径时,Git 通常会检查多个来源的 gitignore
模式,优先级从高到低(在一个优先级内,由最后匹配的模式决定结果):
- 从支持这些模式的命令行中读取的模式。
- 模式从与路径相同目录下的
.gitignore
文件或任何父目录(直到工作树的顶层)中读取,上层文件中的模式会被下层文件中的模式覆盖,直到包含该文件的目录。这些模式相对于.gitignore
文件的位置进行匹配。 项目通常会在其资源库中包含此类.gitignore
文件,其中包含项目构建过程中生成的文件的模式。 - 从
$GIT_DIR/info/exclude
中读取的模式。 - 从配置变量
core.excludesFile
指定的文件中读取的模式。
将模式放入哪个文件取决于模式的使用方式。
- 应受版本控制并通过克隆分发到其他仓库的模式(即所有开发人员都想忽略的文件)应放入
.gitignore
文件。 - 特定于某个仓库但无需与其他相关仓库共享的模式(例如,存在于仓库内部但特定于某个用户工作流程的辅助文件)应放入
$GIT_DIR/info/exclude
文件。 - 用户希望 Git 在任何情况下都忽略的模式(例如,由用户选择的编辑器生成的备份或临时文件),一般会放入用户的
~/.gitconfig
中由core.excludesFile
指定的文件。它的默认值是 XDG_CONFIG_HOME/git/ignore。如果 XDG_CONFIG_HOME 未设置或为空,则使用 $HOME/.config/git/ignore 代替。
底层的 Git 工具,如 git ls-files 和 git read-tree,会读取命令行选项指定的 gitignore 模式,或从命 令行选项指定的文件中读取。 更高层次的 Git 工具,如 git status 和 git add,会使用上述指定来源的模式。
日期格式
- 空行不匹配任何文件,因此可以作为分隔符,以提高可读性。
- 以 # 开头的一行为注释。 对于以散列开头的模式,在第一个散列前面加上反斜杠( "
\
" )。 - 除非使用反斜线("
\
")引号,否则尾部空格将被忽略。 - 一个可选的前缀 "
!``",用于否定模式;任何被先前模式排除的匹配文件都将被重新包含。如果文件的父目录已被排除,则无法重新包含该文件。出于性能考虑,Git 不会列出排除的目录,因此无论在哪里定义,任何包含文件的模式都不会产生影响。 对于以 "
!" 开头的模式,在第一个 "
!" 前面加反斜杠("
`"),例如 "\!important!.txt
"。 - 斜线 "
/
" 用作目录分隔符。分隔符可以出现在.gitignore
搜索模式的开头、中间或结尾。 - 如果在模式的开头或中间(或两者都有)有分隔符,则该模式是相对于特定
.gitignore
文件本身的目录层级而言的。否则,该模式也可能匹配.gitignore
层级以下的任何层级。 - 如果模式末尾有分隔符,则模式只能匹配目录,否则模式既可以匹配文件,也可以匹配目录。
- 例如,模式
doc/frotz/
匹配doc/frotz
目录,但不匹配a/doc/frotz
目录;而frotz/
则匹配frotz
和a/frotz
这两个目录(所有路径都是从.gitignore
文件开始的相对路径)。 - 星号 "
*
" 匹配斜线以外的任何字符。 字符 "?
" 匹配除 "/
" 以外的任何一个字符。 范围符号,如 "[a-zA-Z]
",可用于匹配范围中的一个字符。更详细的说明请参见 fnmatch(3) 和 FNM_PATHNAME 标志。
在与全路径名匹配的模式中,两个连续的星号("**
")可能有特殊含义:
- "
**
"在带斜杠目录之前,表示在所有目录中匹配。例如,"**/foo
"匹配任何文件或目录的"foo
",与模式"foo
"相同。"**/foo/bar
"匹配任何文件或目录中直接位于目录"foo
"之下的"bar
"。 - 路径后跟有 "
/**
" 表示匹配这个目录里面的所有文件。例如,"abc/**
" 匹配相对于.gitignore
文件的位置中目录 "abc
" 内的所有文件,深度无限。 - 一个斜杠后面是两个连续的星号再接上一个斜杠,匹配零个或多个目录。例如,"
a/**/b
" 匹配 "a/b
"、"a/x/b
"、"a/x/y/b
",等等,依此类推。 - 其他连续星号被视为普通星号,将根据前面的规则进行匹配。
配置
可选的配置变量 core.excludesFile
表示包含要排除的文件名模式的文件路径,类似于 $GIT_DIR/info/exclude
。 除 $GIT_DIR/info/exclude
中的模式外,还将使用排除文件中的模式。
注释
使用 gitignore 文件的目的是确保某些不被 Git 追踪的文件不被追踪。
要停止跟踪当前已被跟踪的文件,可使用 git rm --cached 从索引中移除该文件。文件名随后会被添加到 .gitignore
文件中,以防止该文件在以后的提交中被重新引入。
访问工作树中的 .gitignore
文件时,Git 不会跟踪符号链接。这样,当从索引或工作树访问文件时,与从文件系统访问文件时的行为保持一致。
实例
- 模式
hello.*
匹配名称以hello.
开头的任何文件或目录。如果只想将其限制在目录中,而不限制在其子目录中,则可以在模式前加上斜线,即/hello.*
;现在该模式可匹配hello.txt
和hello.c
但不匹配a/hello.java
。 - 模式
foo/
将匹配目录foo
及其下的路径,但不会匹配常规文件或符号链接foo
(这与 Git 中 pathspec 的一般工作方式一致) doc/frotz
和/doc/frotz
模式在任何.gitignore
文件中都有同样的效果。换句话说,如果模式中已经有中间斜线,那么前导斜线就无关紧要了。- 模式
foo/*
匹配foo/test.json
(一个正则文件)和foo/bar
(一个目录),但不匹配foo/bar/hello.c
(一个正则文件),因为模式中的星号不匹配bar/hello.c
,因为bar/hello.c
中含有斜线。
$ git status
[...]
# 未追踪的文件:
[...]
# Documentation/foo.html
# Documentation/gitignore.html
# file.o
# lib.a
# src/internal.o
[...]
$ cat .git/info/exclude
# 忽略在目录树中的所有对象和存档文件
*.[oa]
$ cat Documentation/.gitignore
# 忽略 html 文件,
*.html
# 但追踪自己写的 foo.html
!foo.html
$ git status
[...]
# 未追踪的文件:
[...]
# Documentation/foo.html
[...]
再举一个例子:
$ cat .gitignore
vmlinux*
$ ls arch/foo/kernel/vm*
arch/foo/kernel/vmlinux.lds.S
$ echo '!/vmlinux*' >arch/foo/kernel/.gitignore
第二个 .gitignore 阻止 Git 忽略 arch/foo/kernel/vmlinux.lds.S
。
示例排除除特定目录 foo/bar
以外的所有内容(注意 /*
- 如果没有斜线,通配符也会排除 foo/bar
中的所有内容):
$ cat .gitignore
# 排除 foo/bar 以外的所有内容
/*
!/foo
/foo/*
!/foo/bar
远程仓库
配置SSH秘钥
-
生成自己的秘钥
ssh-keygen -t rsa -b 4096
-
在代码托管平台上传自己的
公钥
-
添加一个config文件,写入以下内容(以
github
为例):#github
Host github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile /.ssh/test
云端同步
将本地代码同步到云端:
git push
将远端代码同步到本地:
git pull
仅获取远程仓库修改:
git fetch
关联云端仓库和本地仓库
-
在某个本地仓库下,执行
git remote add <alias> <url>
alias:表示对应的远程仓库的别名叫做
<alias>
-
执行:
git branch -M main
表示指定分支名称为Main
-
执行
git push -u <alias> main:main
git 推送 -upstream 远程仓库别名 本地分支:远程分支
再次执行可再次绑定一个远程仓库。
分支
创建新的分支
git branch <分支名>
查看当前分支列表
git branch
切换到某个分支
git checkout <分支名>
注意 checkout
命令也可用于回溯,故可使用,
git switch <分支名>
合并分支
git merge <branch name>
删除分支
-
已合并的分支:
git branch -d <branch name>
-
未合并的分支
git branch -D <branch name>
分支冲突
手动处理冲突:
- 手动编辑冲突文件,合并冲突内容
- 添加暂存区
- 提交修改/终端修改(
git merge --abort
)
Rebase
感觉上更像是“嫁接”: