Introduction to Git Commands
导言
Git命令的基本使用。
Git相关概念¶
Git管理的三个区域¶
Working Tree
当前的工作区域Index/Stage
暂存区域,和git stash命令暂存的地方不一样。使用git add xx,就可以将xx添加近Stage里面Repository
提交的历史,即使用git commit提交后的结果
git传输数据使用的协议¶
有4种,
- 本地协议(Local),
- HTTP 协议,
- SSH(Secure Shell)协议
- Git 协议。
但是Local与SSH主要使用在自己搭建的git环境里。这里只介绍其余两种。
http协议
Git 通过 HTTP 通信有两种模式。 在 Git 1.6.6 版本之前只有一个方式可用,十分简单并且通常是只读模式的。 Git 1.6.6 版本引入了一种新的、更智能的协议,让 Git 可以像通过 SSH 那样智能的协商和传输数据。
类似 GitHub 的服务,你在网页上看到的 URL(比如 https://github.com/schacon/simplegit)智能 HTTP 的运行方式和 SSH 及 Git 协议类似,只是运行在标准的 HTTP/S 端口上并且可以使用各种 HTTP 验证机制, 这意味着使用起来会比 SSH 协议简单的多,比如可以使用 HTTP 协议的用户名/密码授权,免去设置 SSH 公钥。
git协议
Git 里的一个特殊的守护进程;它监听在一个特定的端口(9418),类似于 SSH 服务,但是访问无需任何授权。 使用与 SSH 相同的数据传输机制,但是省去了加密和授权的开销。
什么是origin¶
可以理解成本地文件夹的名字-u, --set-upstream set upstream for git pull/status
什么是HEAD¶
HEAD就是当前活跃分支的游标。
形象的记忆就是:你现在在哪儿,HEAD就指向哪儿,所以Git才知道你在那儿!
gitconfig¶
第一次使用需要设置用户信息
# global对当前用户所有仓库
git config --global user.name "shaojiemike"
git config --global user.email "[email protected]"
# local对当前仓库s
git config user.name "username"
git config user.email "email"
使用git config --global --list
查看
[user]
name = aaa
email = aaa.github.com
[alias]
last = log -1
co = checkout
cm = commit
rb = rebase
br = branch
rt = remote
st = status
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -15
lg-graph = log --oneline --graph --decorate --all
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
required = true
git命令用法¶
git diff
:- 相对于常用的
git status
, 也是十分有用的。
- 相对于常用的
git commit
:bash git commit -amend //修正上一次的commit信息 git reset HEAD~ //不小心commit额外文件,但是还没有push时,回退。
git cherry-pick
:- 无需merge,只移动一个commit到其余分支
git patch
- 来实现一次commit的移动
git clone xxx.git “指定目录”
git fetch
合并冗余无效commit¶
更改远程仓库¶
git remote -v #查看
origin [email protected]:Kirrito-k423/BHive-Prediction-Compare.git (fetch)
origin [email protected]:Kirrito-k423/BHive-Prediction-Compare.git (push)
# 修改命令
git remote set-url origin [url]
# set to access repository using token
git remote set-url origin https://Kirrito-k423:<access token>@github.com/Kirrito-k423/dokuwiki-data.git
# 先删后加
git remote rm origin
git remote add origin [url]
标签 tags¶
# 查看标签
git tag
# 添加标签
git tag <tag_name>
git tag -a <tag_name> -m "Tag message"
git tag <tag_name> <commit_hash>
# 删除标签
# .1 删除本地标签
git tag -d <tag_name>
# .2 删除远程标签
git push origin --delete <tag_name>
# push标签
# .1 推送单个标签
git push origin <tag_name>
# .2 推送所有本地标签到远程仓库
git push origin --tags
贮藏与清理 stash¶
有时,当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态, 而这时你想要切换到另一个分支做一点别的事情。 问题是,你不想仅仅因为过会儿回到这一点而为做了一半的工作创建一次提交。 针对这个问题的答案是 git stash
命令。1
常见使用场景
git status
有还未修改的地方- 运行
git stash
或git stash push
,运行 git stash 或 git stash push: - 刚刚贮藏的工作重新应用:
git stash apply
- 其他
- 运行
git stash drop
加上将要移除的贮藏的名字来移除它 - 运行
git stash pop
来应用贮藏然后立即从栈上扔掉它
- 运行
git stash:将当前未commit的信息放入stash栈
git stash pop:将栈顶的存储信息弹出。
git stash apply:使用栈顶的存储信息,但是不弹出。
git stash list:显示栈中列表
git stash save $name:以名字形式进栈
git stash drop $name:按名字索引,删除某个存储信息。
git stash clear:清空存储信息。
撤销 restore¶
// 撤销文件的修改,使文件恢复到暂存区或本地代码库(取决于文件在修改前的状态);
git restore <file>
//把文件从暂存区撤回到工作区,保留文件最后一次修改的内容;
git restore --staged <file>
删除 rm¶
回退 reset¶
都会重置 HEAD 和 branch。
以下面的例子为例
reset --mixed¶
默认的选项。
- 保留工作目录
- 暂存区清空,并把原节点和reset节点的差异的文件放在工作目录.
总而言之就是,工作目录的修改、暂存区的内容以及由 reset 所导致的新的文件差异,都会被放进工作目录
reset --soft¶
--soft则会保留工作目录和stage暂存区中的内容, 并把因为保留工作目录内容所带来的新的文件差异放进暂存区。
假设此时当前 commit 的改动内容是新增了 laughters.txt 文件:git show --stat
执行回退会发现, 原先 HEAD 处 commit 的改动(也就是那个 laughters.txt 文件)也会被放进暂存区:
删除最近的第二次的commit,但是保留最新commit的内容
要删除最近的第二次 commit 但保留最新的 commit 内容,你可以使用以下步骤:
-
查看历史记录: 你可以先用以下命令查看最近的 commit 历史,确认你要删除的 commit:
-
软重置到第二次 commit 之前: 假设你要删除的第二次 commit 的哈希值是
abc123
,你可以用以下命令将 HEAD 移动到它的父 commit: -
重新提交保留的内容: 由于是软重置,工作目录中的文件仍然保持不变,所有修改都处于暂存状态。你可以直接重新提交这些内容:
-
强制推送(如果你在一个远程分支上工作且已经推送过): 如果你已经推送到远程分支,可能需要强制推送:
这样操作之后,第二次 commit 就会被删除,最新 commit 的内容会被保留并重新提交。
reset --hard¶
会重置stage区和工作目录,没有commit的修改会被全部擦掉。(stash的东西应该不会消失)
$ git reset --hard HEAD~3 # 回退上上上一个版本
$ git reset –hard bae128 # 回退到某个版本回退点之前的所有信息。
$ git reset --hard origin/master # 将本地的状态回退到和远程的一样
分支¶
创建¶
决定要解决你的公司使用的问题追踪系统中的 #53 问题。 想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b 参数的 git checkout 命令:2
它是下面两条命令的简写:
从某个commit分支¶
拉远端新分支下来¶
git branch -av
# 方法1 将远程的feature 拉到本地feature1
git checkout -b feature1 origin/feature
# 方法2 默认会在本地建立一个和远程分支名字一样的分支
git checkout -t origin/feature
# 方法3 注意不要fetch到当前分支,会提示:fatal: 拒绝获取到非纯仓库的当前分支
git fetch origin b1:b1
本地覆盖远端某分支¶
or, more generally正常切换¶
分支上提交¶
分支historypull¶
This will merge the history of the “master” branch onto our “dev” branch. You can use the rebase command with any base commit reference合并¶
情况1:fast-forward¶
基于 master 分支的紧急问题分支 hotfix branch 你可以运行你的测试,确保你的修改是正确的,然后将 hotfix 分支合并回你的 master 分支来部署到线上。 你可以使用 git merge 命令来达到上述目的:
想要合并的分支 hotfix 所指向的提交 C4 是你所在的提交 C2 的直接后继, 因此 Git 会直接将指针向前移动。换句话说,当你试图合并两个分支时, 如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候, 只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。
情况2:解决diverged分歧¶
你的开发历史从一个更早的地方开始分叉开来(diverged)。 因为,master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4 和 C5)以及这两个分支的公共祖先(C2),做一个简单的三方合并。
手动解决分歧¶
文件格式如下:
<<<<<<< HEAD:index.html
a-----------balabala------------
=======
b-----------balabala------------
>>>>>>> iss53:index.html
只需要修改成想要的,然后 git add
。git就会认为git冲突已经被处理。
最好使用 git commit
来提交,message应该是默认的 Merge branch 'iss53'
删除¶
参考文献¶
https://www.jianshu.com/p/c2ec5f06cf1a
https://blog.csdn.net/weixin_36572983/article/details/106340607
git restore: https://www.cnblogs.com/teach/p/13997323.html