# git-demo
**Repository Path**: stone100/git-demo
## Basic Information
- **Project Name**: git-demo
- **Description**: Git命令使用Demo
- **Primary Language**: Dart
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: https://www.jianshu.com/p/fa4cd74f2f0e
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2022-02-17
- **Last Updated**: 2022-02-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Git, Markdown, GitHub, Gitee, gitcode
## README
# git-demo
# 介绍
Git命令使用Demo
# 文档:
1. 如何配置SSH Key:https://gitee.com/stone100/git-demo/blob/master/SSH-key.md
2. git的基本用法:https://www.jianshu.com/p/fa4cd74f2f0e
3. [Pull request 以及 不同仓库之间的同步](https://gitee.com/stone100/git-demo/blob/master/pull-requst-and-repo-sync.md)
4. 更多高级用法:TODO
5. 复杂一点的用法, 请看下面:
# 补充
#### 一、本地分支与远程分支的关联:
```shell
$ git branch -u remotes/origin/master # 设置当前分支与远程分支相关联 (使用 git branch -a 来查看远程分支)
$ git pull --rebase # 设置了分支的关联分支后, pull 就不再需要指明远程仓库和远程分支了
# 如果本地分支没有与远程分支关联, 那么要拉取哪个远程仓库的哪个分支, 就需要明确的指定, 如:
$ git pull --rebase origin master # 指明远程仓库为origin, 分支为origin 上的master.
$ git branch --unset-upstream # 取消当前分支与远程分支的关联
# https://www.cnblogs.com/zhou-chao/p/7678899.html
# 格式: git branch --set-upstream-to= current-branch
# 如下:
$ git branch --sett-upstream-to=origin/master master
# 假设要删除branch-a的远程分支,我们需要先把分支切换到master,
# 因为你现在所在的分支就是branch-a,在这个分支下,是不能删除它的。
# 1. 切换到其他分支
$ git checkout master
# 2. 删除远程分支
$ git push origin --delete branch-a
```
#### 二、推送本地分支到远程仓库 并 在远程仓库创建新分支 (如果远程分支不存在的话就创建)
```shell
# push命令的格式:
# git push <远程仓库名> <本地分支名>:<远程分支名>
# 尖括号的部分都可以省略 (如果本地分支关联了远程分支)
# 远程仓库名, 就是 git remote add 命令添加远程仓库时的那个名称, 如下:
# git remote add <远程仓库名> <远程仓库url地址>, 就是这个命令格式中 <远程仓库名>.
# 如:
$ git remote add origin https://gitee.com/stone100/git-demo.git # 远程仓库名为origin
# push一个本地分支到远程仓库 (如果远程仓库中没有这个分支, 则创建)
$ git push origin branch-a:branch-a
# 注意远程分支名就只是是分支名 , 不需要前缀remotes/origin,
# 也不需要前缀origin (origin远程仓库名,跟分支没有关系)
# 下面的写法会导致创建名为 orgin/master 和 remotes/origin/master 分支
# git push origin master:origin/master
# git push origin master:remotes/origin:master
# git branch -a # 会输出:
# remotes/origin/origin/master
# remotes/origin/remotes/origin/master
$ git branch -a
master
* new-branch
remotes/origin/master
remotes/origin/new-branch
# 远程仓库的名称是以 "remotes//" 开头的, 我这例的远程仓库名 repo-name 是 origin,
# 因此远程仓库的名称就是: remotes/origin/master
# remotes/origin/new-branch
# 查看远程仓库的 仓库地址:
$ git remote -v
```
#### 三、如何查看本地分支所关联的远程分支??
```shell
$ git branch -vv
main 60110f5 init repo
* master e3b119d [origin/master] 更新文档 (README.md文件)
# main 分支没有关联远程分支
# master分支关联的远程分支是master, [origin/master] 前面的origin是远程仓库的名称
# 用 "git remote add" 命令添加远程仓库时为远程仓库起的名称
# git remote add 的格式如下:
# git remote add <远程仓库名> <远程仓库URL>
```
#### 四、查看提交日志
```shell
# 查看日志 (摘要)
$ git log
$ 查看日志 (详细信息)
$ git ll # ll 是 alias, git config --list 可以查看到ll的具体情况
```
#### 五、配置信息
```shell
# 查看用户名
$ git config --global user.name
stone.zhou
# 查看用户的邮件地址
$ git config --global user.email
xxxxxxxxx@xxx.xxx
# 配置用户名
$ git config --global user.name "xxx"
# 配置用户的邮件地址
$ git config --global user.email "someone@xxx.xxx"
# 用户名 和 用户的邮件地址会在commit时用到, 如:
$ git ll
commit 60110f5 (HEAD -> main)
Author: 用户名 <用户的邮件地址>
Date: Wed Feb 16 17:28:21 2022 +0800
init repo
Demo1.cpp | 45 +++++++++++++++++++++++++
Demo1.h | 21 ++++++++++++
Demo1.java | 36 ++++++++++++++++++++
JniDemo.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++
JniDemo.h | 29 ++++++++++++++++
JniDemoMain.java | 26 ++++++++++++++
com/stone/demo/JniDemo.java | 41 +++++++++++++++++++++++
7 files changed, 280 insertions(+)
# "git ll" 输出的用户提交信息, 其中第二行, 就是 "git config --global" 命令设置的用户名和邮件地址:
# 格式为:
# Author: user.name
# "git config --global" 是在操作 "~/.gitconfig" 文件,
# 我们用 "git config --global" 命令就是在存取 "~/.gitconfig" 文件中的内容
```
#### 六、证件小助手
https://blog.csdn.net/weixin_45115705/article/details/105164848
https://blog.csdn.net/u012163684/article/details/52433645/
```shell
# 查看credential相关的帮助
$ git help -a | grep credential
credential Retrieve and store user credentials
credential-cache Helper to temporarily store passwords in memory
credential-store Helper to store credentials on disk
credential-osxkeychain
# 1. cache 内存中临时存储
# 2. store 存储在磁盘上 (全局: ~/.git-credentials ; 局部: /.git-credentials)
# store (~/.git-credentials) 是明文存储的, 十分危险
# 3. osxkeychain
# 查看
$ git config --global credential.helper
# 设置
$ git config --global credential.helper osxkeychain
# 删除某个配置, 如:
$ git config --global --unset credential.helper
# 查看所有配置
$ git config -list
# 用户目录下的3个git相关的配置文件:
# ~/.gitconfig # git的全局配置文件 ( "git config --global" 可以操作这个文件的内容)
# ~/.git-credentials # github/gitee/gitcode 等网站的密码存储文件
# ~/.gitk # gitk是一个git的图形界面客户端, ~/.gitk 是gik的配置文件
```
#### 七、复原到修改之前 (丢弃修改的内容, 内容还没有add)
```shell
# 如果切换到一个分支, 然后不小心更改了一些内容,
# 但是你又不想要这些内容 (注意: 这些更改的内容是没有 "git add" 过的),
# 这时候就需要抛弃更改的内容, 使用 "git restore" 命令来实现.
$ git restore README.md # 抛弃更改的内容 (或者说是: 复原到没有更改的状态)
```
#### 八、合并 ( git merge 和 git rebase )
```shell
# https://www.jianshu.com/p/58a166f24c81
# git merge 的语法格式, 如下:
$ git merge --help
usage: git merge [] [...]
or: git merge --abort
or: git merge --continue
# git merge --commit commit-hash # 合并后生成一个commit (默认就是 --commit)
# --commit 参数说明:
# --commit perform a commit if the merge succeeds (default)
# 如何查看commit-hash?
# 方法一: git branch -vv 或者 git branch -vv
# git branch -v 或 git branch -vv 会列出每个分支最新的commit-hash
# 方法二: 切换到要被合并的分支上, 然后 git log 或者 git ll 查看提交记录, 提交记录中有commit-hash, 复制commit-hash, 然后切回来, 然后再 git merge --abort commit-hash
# 这种办法太麻烦了, 切来切去.
$ git merge --abort # 合并出问题时, 用--abort参数来指示回滚到merge之前
$ git merge --continue # 合并时产生的冲突解已决 且 已经add了修改后的文件,
# 那么可以用 --continue 来指示继续合并
# 下面是一次没有冲突的合并 (当前分支为master, 使用 "git branch -v" 来查看其他分支的最新commit-hash)
$ git branch -v
* master 7f12bc8 更新文档
new-branch 120fed8 更新文档
$ git merge 120fed8
Updating 7f12bc8..120fed8
Fast-forward
README.md | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
SSH-key.md | 29 ++++++++++-
2 files changed, 194 insertions(+), 4 deletions(-)
# 发送冲突时的提交流程:
# 1. git merge, 产生冲突 # 冲突
# 2. 解决冲突 # 解决冲突
# 3. git add 解决了冲突之后的文件 # 添加文件
# 4. git merge --continue # 解决冲突后继续merge
=================================================================
=================================================================
=================================================================
=================================================================
=================================================================
# git rebase: https://www.jianshu.com/p/4a8f4af4e803
$ git rebase --help # 查看帮助
usage: git rebase [-i] [options] [--exec ] [--onto | --keep-base] [ []]
or: git rebase [-i] [options] [--exec ] [--onto ] --root []
or: git rebase --continue | --abort | --skip | --edit-todo
# 交互模式
# -i, --interactive let the user edit the list of commits to rebase
$ git rebase other-branch # 将其他分支与当前分支合并
$ git rebase other-branch current-branch # 和上面这句效果一样
$ git rebase --abort # --abort 遇到错误时, 回到rebase前的状态
$ git rebase --continue # 冲突已经解决 且 编辑或的冲突文件都add后, 用--continue来指示继续rebase
# rebase发生冲突时的, 处理流程
# 1. git rebase # 冲突
# 2. 解决冲突 # 解决冲突
# 3. git add 解决了冲突之后的文件 # 添加文件
# 4. git rebase --continue # 解决冲突后继续rebase (相当于提交)
========================================================================
========================================================================
# 别名 (alias):
# https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-Git-%E5%88%AB%E5%90%8D
# "git ll" 中的ll就是一个alias
$ git alias # 列出所有的别名
$ git diff # 查看改动
# git提交流程图:
# https://www.cnblogs.com/lclf/p/14432235.html
# 查看历史提交
# http://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%9F%A5%E7%9C%8B%E6%8F%90%E4%BA%A4%E5%8E%86%E5%8F%B2
$ git log --graph # 显示分支的提交路径图
```
#### 九、如何删除远程分支 ??
```shell
$ git branch -a # 查看所有分支 (本地 和 远程)
master
new-branch
* test1
remotes/origin/master
remotes/origin/new-branch
remotes/origin/remotes/origin/master
# -u 是 --set-upstream-to 的简写;
# # 最后一个参数写 git branch -a 列出的名称的全称
$ git branch -u remotes/origin/remotes/origin/master
$ git branch --unset-upstream # 取消本地当前分支与远程分支的关联
$ git branch -vv # 查看本地分支的关联情况
master 6dff888 [origin/master] 更新文档
new-branch 120fed8 更新文档
* test1 6dff888 [origin/remotes/origin/master: ahead 6] 更新文档
# git branch -vv 的输出格式 (方括号中的格式): 远程仓库名/<远程分支名>
# git branch -a 的输出格式是: remotes/<远程仓库名>/<远程仓库名>
# 最后一个参数写 "git branch -a" 列出的分支的名称的全称
$ git branch --set-upstream-to=remotes/origin/remotes/origin/master
$ git push origin --delete test1
error: unable to delete 'test1': remote ref does not exist
error: failed to push some refs to 'https://gitee.com/stone100/git-demo.git'
# 将本地分支推送到远程仓库
# 注意: 此时远程仓库没有与本地对应的分支, 命令的结果是:
# 远程仓库创建一个和本地当前分支相同的分支,
$ git push origin HEAD
# 当一个本地分支 与 它所关联的远程分支不匹配时 (远程分支的commit与本地的完全不一致 名称 与本地分支的名称也不一样), 会输出如下信息:
$ git push origin
fatal: The upstream branch of your current branch does not match
the name of your current branch. To push to the upstream branch
on the remote, use
git push origin HEAD:remotes/origin/master
To push to the branch of the same name on the remote, use
git push origin HEAD
# 删除远程分支
$ git push origin --delete # 只写远程分支名就行
# git branch -a 输出的远程分支的格式是:
# remotes//
# 注意: 不能删除当前分支关联的远程分支
```
#### 十、git stash
https://blog.csdn.net/stone_yw/article/details/80795669
```shell
# git stash 语法:
$ git stash --help # 查看git stash的用法, 如下:
SYNOPSIS
git stash list []
git stash show [-u|--include-untracked|--only-untracked] [] []
git stash drop [-q|--quiet] []
git stash ( pop | apply ) [--index] [-q|--quiet] []
git stash branch []
git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [-m|--message ]
[--pathspec-from-file= [--pathspec-file-nul]]
[--] [...]]
git stash clear
git stash create []
git stash store [-m|--message ] [-q|--quiet]
$ git stash list # 列出暂存中的内容
$ git stash # 暂存修改内容
$ git stash save "可以添加一点注释" # "git stash save" 可以添加注释
# stash的内容是以栈的形式存储的, git stash pop 会弹出最近一个stash的内容
$ git stash pop # 弹出最近的stash
$ git stash apply
# 将堆栈中的内容应用到当前目录,不同于git stash pop,该命令不会将内容从堆栈中删除,
# 也就说该命令能够将堆栈的内容多次应用到工作目录中,适应于多个分支的情况。
# 删除某个stash
# git stash drop
# 如:
$ git stash drop stash@{0}
$ git stash show # 查看堆栈中最新保存的stash和当前目录的差异。
$ git stash show stash@{1} # 查看具体某个stash和当前目录的差异
# 上面两种输出信息只是摘要, 没有详细的信息, 加上-p参数可以查看具体改动的内容
$ git stash show stash@{1} -p # 查看stash@{1} 的具体改动内容
# 从stash上创建分支
$ git stash branch new-branch # 从最新的stash上创建分支 并 理解切换到新分支, 创建分支后会删除最新的stash
Switched to a new branch 'new-branch'
On branch new-branch
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified: hello.c
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (5d0591f5af5da4409b58b0799c597c6cd39fdb87)
# 如何从指定的stash上创建分支?? 格式如下:
# git stash branch 分支名称 stash名称
# 如:
$ git stash branch new-branch stash@{2}
# 从指定的stash上创建分支 (创建分支后不会切换到新创建的分支, 也不会删除指定stash),
# 注意和不指定stash时的区别!!!!!
$ git stash clear # 清除所有暂存 (清楚所有stash)
# 案例 (存 -> 看 -> 删) :
$ git stash save "第一个暂存内容"
Saved working directory and index state On test1: 第一个暂存内容
$ git stash list
stash@{0}: On test1: 第一个暂存内容
$ git stash drop stash@{0}
Dropped stash@{0} (a3c35049ad336478ad93e75d5012009204dc61e9)
```
####十一、删除分支
```shell
# 删除分支, 命令格式:
# git branch -d branch-name
# 强行删除: git branch -D branch-name
$ git branch -d new-branch-1 # -d 删除分支 (没有合并的分支, 删除时会有提示)
error: The branch 'new-branch-1' is not fully merged.
If you are sure you want to delete it, run 'git branch -D new-branch-1'.
$ git branch -D new-branch-1 # -D 强制删除
# 不能删除当前分支, 要删除当前分支, 需要切换到其他分支再来删除
$ git branch
master
* new-branch
$ git branch -d new-branch # 删除当前分支会报错
error: Cannot delete branch 'new-branch' checked out at '/Users/stone/works/git-demo/demo1'
$ git checkout master # 切换
$ git branch -d new-branch # 删除
################################################################
```
####十二、撤销add内容
https://www.cnblogs.com/mingerlcm/p/12495491.html
```shell
# 撤销add的内容
$ git reset HEAD .
# 假如add过后的状态是 ADDED, add之前的状态是ADD,
# 那么 "git reset HEAD ." 的作用就是: ADDED => ADD
# 注意: 改动内容并不会删除, 看下面的图
# 强制回退到某个提交
$ git reset --hard commit-hash
```
`git reset HEAD .` 的作用:

####十三、查看某个commit 的修改内容:
```shell
# 具体步骤:
# 1. git log 找的要查看的commit-hash
# 2. git show commit-hash
# 如:
# 找到要查看的提交记录的 commit-hash
$ git log
commit af691547b1eb12dc1b27e73742c0d11d34864013 (HEAD -> test)
Author: stone.zhou
Date: Fri Feb 18 11:46:18 2022 +0800
11111
commit ee07bd6951ba5845ccf3738ff73435f53eb71d73 (tag-01, master, dev)
Author: stone.zhou
Date: Wed Feb 16 16:52:31 2022 +0800
添加第一个文件
# 查看 commit-hash 所指定的这次提交 的改动内容
$ git show ee07bd6951ba5845ccf3738ff73435f53eb71d73
commit ee07bd6951ba5845ccf3738ff73435f53eb71d73 (tag-01, master, dev)
Author: stone.zhou
Date: Wed Feb 16 16:52:31 2022 +0800
添加第一个文件
diff --git a/hello.c b/hello.c
new file mode 100644
index 0000000..8d2ffb4
--- /dev/null
+++ b/hello.c
@@ -0,0 +1,6 @@
+#include
+
+int main(int argc, char** argv) {
+ printf("Hello world !\n");
+ return 0;
+}
```
#### 回退命令
```shell
// TODO
# git checkout
# git reset
# git revert
# git restore
```
#### git stage
https://www.jianshu.com/p/058164fdfc3f
#### 查看提交记录
```shell
$ git log --all # 和 git log 差不多
$ git log --stat # 查看提交记录, 有增加(+), 删除(-) 等更改信息
# 用关键字来过滤提交记录
# git log --grep keyword
# 如:
$ git log --grep 1111
$ git log --grep 添加
# git log --pretty=format # 以某种格式来输出提交记录
# format的格式, 参考: https://www.cnblogs.com/lenomirei/p/8379457.html
$ git log --pretty=oneline # 单行查看提交记录 (长的commit-hash)
$ git log --oneline # 单行查看提交记录 (短的commit-hash)
$ git log --graph # 输出分支图
# 单行显示提交记录 (输出的是短hash)
$ git log --oneline
af69154 (HEAD -> test) 11111
ee07bd6 (tag-01, master, dev) 添加第一个文件
$ git log # 简单的提交信息
$ git log -p # 有文件修改的信息
# 查看某个提交记录 (用commit-hash指定)
# 注意: git log 必须使用长hash
# git log long-commit-hash # 只展示提交记录的摘要信息
# git log -p long-commit-hash # 展示具体修改的内容
# 如:
$ git log ee07bd6951ba5845ccf3738ff73435f53eb71d73
commit ee07bd6951ba5845ccf3738ff73435f53eb71d73 (tag-01, master, dev)
Author: stone.zhou
Date: Wed Feb 16 16:52:31 2022 +0800
添加第一个文件
$ git log -p ee07bd6951ba5845ccf3738ff73435f53eb71d73
commit ee07bd6951ba5845ccf3738ff73435f53eb71d73 (tag-01, master, dev)
Author: stone.zhou
Date: Wed Feb 16 16:52:31 2022 +0800
添加第一个文件
diff --git a/hello.c b/hello.c
new file mode 100644
index 0000000..8d2ffb4
--- /dev/null
+++ b/hello.c
@@ -0,0 +1,6 @@
+#include
+
+int main(int argc, char** argv) {
+ printf("Hello world !\n");
+ return 0;
+}
$ git show # 显示最近一次提交的详细信息 (有文件的修改信息)
$ git show --name-only # 显示最近一次提交的信息 (没有文件修改的详细信息)
# 短hash 和 长hash 都行 (git log --oneline 输出的hash 和 git log 输出的hash都行)
$ git show commit-hash
```
```shell
# 添加, 提交 一步搞定
$ git commit -a -m "这是注释" # -a 表示 add
# 注意: Untracked files 是不能被 -a 提交的
# -a 选项只会add那些, Tracked files
# rebase格式:
# git rebase
# 如:
$ git rebase test1
# 删除远程分支的命令格式如下:
# git push origin --delete <远程分支名>
# 远程仓库名一般设置为origin, 因此:
# git push origin --delete <远程分支名>
# 说明:
# 1. 不会删除与远程分支关联的本地分支
# 2. 不会删除本地分支与远程分支的关联信息 (你可以切换到本地的test1分支, 然后 git branch --unset-upstream 来删除无效的关联信息)
# 注意: 远程分支的名称不要加 "remotes/<远程仓库名>/" 或 "远程仓库名/", 只写远程分支名就行,
# 下面是两种错误写法:
# git push origin --delete origin/test1
# git push origin --delete remotes/origin/test1
$ git push origin --delete test1 # 正确写法
# 不能删除当前分支关联的远程分支
# 正确的做饭:
# 1. 切换到其他分支, 再删除
# a. git checkout
# b. git push --delete
# 2. 解除当前分支与远程分支的关联, 再删除
# a. git branch --unset-upstream
# b. git push --delete
#
# remote-repository:
# 是 git remote add 中的
# 将本地分支推送到远程仓库 (本地分支不会与远程刚刚推送上去的远程分支关联)
# git push origin :
# 如:
$ git push origin test3:test3 # 指定本地分支与远程分支的名称
# 与当前的分支没有关系, 如当前分支是 current, 那么我可以推送一个本地分支 test 到远程分支上去:
$ git push origin test:test
# 将本地的当前分支推送到远程仓库, 远程仓库的分支名称与本地分支名相同 (远程分支与本地分支不会关联)
$ git push origin HEAD
# 创建新分支并切换, 还指定关联的远程分支
# 格式: git checkout -b /
# 如:
$ git checkout -b test2 origin/test2
```
git文档
https://git-scm.com/book/zh/v2