hunting/doc/git/git.md
2023-09-02 23:11:34 +08:00

300 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# git初步使用
```
git init
//设置仓库的公共信息这个user信息会体现在commit信息中
git config --global user.name "yourname"
git config --global user.email "your email"
//在远程仓库方面有两种模式一种ssh一种https
//https 简单方便但每次push都要输入密码
git remote add origin https://github.com/yourgit/your warehouse.git
git add --all
git commit -m "you commit info"
git push -u origin master //第一次以后可以用git push简化
//ssh模式 需要先在github中添加自己的sshkey
//首先看自己的本地目录下是否有 .ssh目录
//没有的话
ssh-keygen -t rsa -C "youremail@example.com"
//并将 .ssh/id_rsa.pub中的key添加到github.com中
git remote add origin git@github.com:yourgit/your warehouse.git
```
## git alias
~/.gitconfig配置文件可以配置当前用户全局git属性当然每个字母了git仓库下也可以有一个.gitconfig配置当前仓库属性属性中有一个alias属性来给git一些命令提供别名方便使用
配置方法参考 ```git config --help```
下面给出我的配置仅供参考
```shell
[user]
email = liaojia138797@163.com
name = ljx
[alias]
st = status
co = checkout
br = branch
hist = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short
type = cat-file -t
dump = cat-file -p
cm = commit -m
df = diff
[core]
editor = vim
```
## gitignore
```
所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
可以使用标准的 glob 模式匹配。
匹配模式最后跟反斜杠(/)说明要忽略的是目录。
要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc]匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a要么匹配一个 b要么匹配一个 c问号?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。
```
## git命令
* git rm / git rm --cached
```
//当我们要删除文件filename 并且工作区也不需要这个文件了
git rm filename
//当我们需要删除暂存区或者分支的文件,但是本地需要保留这个文件,只是不希望此文件被版本控制时
git rm --cached filename
```
* git branch
```
查看本地分支:$ git branch
查看远程分支:$ git branch -r
创建本地分支:$ git branch [name] ----注意新分支创建后不会自动切换为当前分支
切换分支:$ git checkout [name]
创建新分支并立即切换到新分支:$ git checkout -b [name]
删除分支:$ git branch -d [name] ---- -d选项只能删除已经参与了合并的分支对于未有合并的分支是无法删除的。如果想强制删除一个分支可以使用-D选项
合并分支:$ git merge [name] ----将名称为[name]的分支与当前分支合并
创建远程分支(本地分支push到远程)$ git push origin [name]
删除远程分支:$ git push origin :heads/[name] 
或 $ git push origin :[name] 
```
* git remote
```c++
查看远程仓库:$ git remote -v
添加远程仓库:$ git remote add [name] [url]
删除远程仓库:$ git remote rm [name]
修改远程仓库:$ git remote set-url --push [name] [newUrl]
拉取远程仓库:$ git pull [remoteName] [localBranchName]
推送远程仓库:$ git push [remoteName] [localBranchName]
 
*如果想把本地的某个分支test提交到远程仓库并作为远程仓库的master分支或者作为另外一个名叫test的分支如下
$git push origin test:master   // 提交本地test分支作为远程的master分支
$git push origin test:test     // 提交本地test分支作为远程的test分支
```
* git merge
```
//合并a分支到master
git checkout master
git merge a
```
* git tag
```
//标签
git tag v1.0
```
* git reset
```
当将不想staging的文件add进了index可以
git reset HEAD <file>
git reset --hard xxx
xxx可以是connid可以退回到此id的版本
hard (修改版本库,修改暂存区,修改工作区)
--hard HEAD1 (或是commid)意为将版本库回退1个版本但是不仅仅是将本地版本库的头指针全部重置到指定版本也会重置暂存区并且会将工作区代码也回退到这个版本
这个操作非常危险需要谨慎执行如果不小心丢失掉了一些commit的话执行
git reflog找到丢失掉的commit再次git reset --hard 回去
git reset --soft xxx
soft (修改版本库,保留暂存区,保留工作区)
--soft HEAD1 意为将版本库软回退1个版本所谓软回退表示将本地版本库的头指针全部重置到指定版本且将这次提交之后的所有变更都移动到暂存区。
意思是当你commit后又执行 git reset --soft HEAD^1,你本次commit直接从repository退回到index未commit状态如果是退回多个版本则多次commit回退
不加参数(--mixed 
意思是不删除工作空间改动代码撤销commit并且撤销git add . 操作
这个为默认参数,git reset --mixed HEAD^ 和 git reset HEAD^ 效果是一样的。
git revert xxx
revert
-- git revert 也是撤销命令区别在于reset是指向原地或者向前移动指针git revert是创建一个commit来覆盖当前的commit指针向后移动。
https://www.jianshu.com/p/c2ec5f06cf1a
git reset --hard <commit>:
1.替换引用的指向.引用指向新的提交ID;
2.替换暂存区.替换后,暂存区的内容和引用指向的目录树一致;
3.替换工作区.替换后,工作区的内容变得和暂存区一致,也和HEAD所指向的目录树内容相同.
git reset --soft <commit>:
1.替换引用的指向.引用指向新的提交ID.
即只更改引用的指向,不该编暂存区和工作区.
git reset --mixed <commit>或git reset <commit>:
1.替换引用的指向.引用指向新的提交ID;
2.替换暂存区.替换后,暂存区的内容和引用指向的目录树一致;
即更改引用的指向及重置暂存区,但是工作区不变.
实例:
git reset
仅用HEAD指向的目录树重置暂存区,工作区不受影响,相当于将之前用git add命令更新到暂存区的内容撤出暂存区.引用也未改变,因为引用重置到HEAD相当于没有重置.
git reset HEAD
同上
git reset -- filename
仅将文件filename的改动撤出暂存区,暂存区中其他文件不该变.相当于git add filename的反向操作.
git reset HEAD filename
同上
git reset --soft  HEAD^
工作区和暂存区不改变,但是引用向前回退一次.当对最新提交的提交说明或提交不满意更改时,撤销最新的提交一遍重新提交.
git reset HEAD^
工作区不变,但是暂存区会回退到上一次提交之前,引用也会回退一次.
git reset --mixed HEAD^
同上
git reset --hard HEAD^
彻底撤销最近的提交.引用回退到前一次,而且工作区和暂存区都会回退到上一次提交的状态.自上一次以来的提交全部丢失.
```
* git checkout
```
git  checkout 
git checkout <commit> [--] <paths>
1.<commit>是可选项,如果省略则相当于从暂存区进行检出.和reset命令大不相同:重置的默认值是HEAD,而检出的默认值是暂存区.
2.因此重置一般用于重置暂存区(除非使用--hard,否则不重置工作区),而检出命令主要是覆盖工作区(如果<commit>不省略,也会替换暂存区中相应的文件).
3.该命令不会改变HEAD的头指针,主要用于指定版本文件覆盖工作区中对应的文件.如果省略<commit>,则会用暂存区的文件覆盖工作区的文件,否则用指定提交中的文件覆盖暂存区和工作区中的对应文件.
git checkout  <branch>
1.会改变HEAD头指针.之所以后面的参数写作<branch>,是因为只有HEAD切换到一个分支才可以对提交进行跟踪,否则仍然会进入"分离头指针"的状态.在"分离头指针"的状态下的提交并不能被引用关联到,从而可能丢失.所以该命令主要作用是切换分支.
2.如果省略<branch>则相当于对工作区进行状态检查.
实例:
git checkout branch
检出branch分支,更新HEAD以指向branch分支,以及用branch指向的树更新暂存区和工作区.
git checkout
汇总显示工作区,暂存区与HEAD的差异
git checkout HEAD
同上
git checkout -- filename
用暂存区中的filename文件来覆盖工作区中的filename文件.相当于取消自上次执行git add filename以来(如果执行过)的本地修改
//放弃修改回到以前的状态
//这条命令有些危险,所有对文件的修改都没有了,因为我们刚刚把之前版本的文件复制过来重写了此文件。所以在用这条命令前,请务必确定真的不再需要保留刚才的修改
git checkout branch -- filename
维持HEAD的指向不变.用branch所指向的提交中的filename替换暂存区和工作区中相应的文件.会将暂存区和工作区中的filename直接覆盖
git checkout -- .或者git checkout .
会取消本地所有修改,相当于用暂存区的所有文件直接覆盖本地文件.
```
* git stash
```
当你做某个工作时遇到紧急情况需要切换branch又不想commit当前未完成工作来造成不必要的繁琐log时执行
git stash
或者执行
git stash save "something"
当你完成紧急工作后想要继续当时停下来的开发
在原分支 git stash save -a "messeag",网上很多很多资料都没有加 -a 这个option选项我想他们的代码开发可能都是在原代码上进行修改吧。而对于在项目里加入了代码新文件的开发来说-a选项才会将新加入的代码文件同时放入暂存区。
git stash pop可以弹回到最后一次的stash
也可以
git stash list查看有几个stash
git stash apply stash@{}来回到你想要的stash
git stash clear清除所有缓存的stash
git stash show stash@{}来查看diff
stash信息不回被删除除非你弹回去了但如果你不想要那时候的stash了。比如认为当时的改动是错误的你可以
git stash drop <stash@{id}>  如果不加stash编号默认的就是删除最新的也就是编号为0的那个加编号就是删除指定编号的stash。git  stash clear 是清除所有stash,整个世界一下子清净了!
git stash pop   git stash apply <stash@{id}> 的区别。
当我使用git stash pop  git stash apply 几次以后我发现stash  list 好像比我预计的多了几个stash。于是我便上网去了解了一下这两个命令的区别。原来git stash pop stash@{id}命令会在执行后将对应的stash id 从stash list里删除 git stash apply stash@{id} 命令则会继续保存stash id。对于有点强迫症的我来说是容不下越来越多的陈旧stash id 仍然存在的所以我更习惯于用git stash pop 命令。
```
* git log
```
$ git log -p -2
//我们常用 -p 选项展开显示每次提交的内容差异 -2 则仅显示最近的两次更新
$ git log -U1 --word-diff
//上下文行数1行以单词来看差异单词前后以+wold+ - - 表示出来
```
* git commit
```
$ git commit amend
//有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用 --amend 选项重新提交
```
* git clone
```
git clone git@github.com:ljx791863565/xxx.git
git clone https://github.com/ljx791863565/xxx.git
```
* git diff
```
//比较暂存区与版本库的改动
git diff --staged
git diff commid1 commid2
git diff branch1 branch2
git diff 对比工作区(未 git add)和暂存区(git add 之后)
git diff --cached: 对比暂存区(git add 之后)和版本库(git commit 之后)
git diff HEAD: 对比工作区(未 git add)和版本库(git commit 之后)
```
* git config
Git 提供了一个叫做 git config 的工具译注实际是 git-config 命令只不过可以通过 git 加一个名字来呼叫此命令。专门用来配置或读取相应的工作环境变量。而正是由这些环境变量决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:
* /etc/gitconfig 文件系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system选项读写的就是这个文件。
* ~/.gitconfig 文件用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global选项读写的就是这个文件。
当前项目的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。
供了一个叫做 git config 的工具译注实际是 git-config 命令只不过可以通过 git 加一个名字来呼叫此命令。专门用来配置或读取相应的工作环境变量。而正是由这些环境变量决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:
* /etc/gitconfig 文件系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system选项读写的就是这个文件。
* ~/.gitconfig 文件用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global选项读写的就是这个文件。
当前项目的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。
```
第一个要配置的是你个人的用户名称和电子邮件地址。这两条配置很重要,每次 Git 提交时都会引用这两条信息,说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录:
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
如果用了 --global 选项那么更改的配置文件就是位于你用户主目录下的那个以后你所有的项目都会默认使用这里配置的用户信息。如果要在某个特定的项目中使用其他名字或者电邮只要去掉 --global选项重新配置即可新的设定保存在当前项目的 .git/config 文件里。
还有一个比较常用的是,在解决合并冲突时使用哪种差异分析工具。比如要改用 vimdiff 的话:
$ git config --global merge.tool vimdiff
Git 可以理解 kdiff3tkdiffmeldxxdiffemergevimdiffgvimdiffecmerge和 opendiff 等合并工具的输出信息。当然,你也可以指定使用自己开发的工具
```
## git问题解决
* fatal: object 906d1543778b940af481c0ca7f5ce9d3d9771140 is corrupted
```
rm -rf .git
git init
git remote add origin git@github.com:yourgit/yourwarehouse.git
git fetch
git reset --hard origin/master
```
[https://blog.csdn.net/dengjianqiang2011/article/details/9260435](https://blog.csdn.net/dengjianqiang2011/article/details/9260435)