跳转至

Introduction to Git Commands

导言

Git命令的基本使用。

Git相关概念

Git管理的三个区域

  1. Working Tree 当前的工作区域
  2. Index/Stage 暂存区域,和git stash命令暂存的地方不一样。使用git add xx,就可以将xx添加近Stage里面
  3. 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
git fetch -p origin

    -p, --prune           清除远程已经不存在的分支的跟踪分支
    -P, --prune-tags      清除远程不存在的本地标签,并且替换变更标签

合并冗余无效commit

来合并冗余无效的commit, 参考这篇例子很详细

git rebase -i cf7e875 

更改远程仓库

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

常见使用场景

  1. git status有还未修改的地方
  2. 运行 git stashgit stash push,运行 git stash 或 git stash push:
  3. 刚刚贮藏的工作重新应用:git stash apply
  4. 其他
    1. 运行 git stash drop 加上将要移除的贮藏的名字来移除它
    2. 运行 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

//删除暂存区和工作区的文件
git rm -f 文件名

//仅仅删除暂存区里的文件    
git rm --cache 文件名

回退 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 内容,你可以使用以下步骤:

  1. 查看历史记录: 你可以先用以下命令查看最近的 commit 历史,确认你要删除的 commit:

    git log --oneline
    

  2. 软重置到第二次 commit 之前: 假设你要删除的第二次 commit 的哈希值是 abc123,你可以用以下命令将 HEAD 移动到它的父 commit:

    git reset --soft abc123^
    

  3. 重新提交保留的内容: 由于是软重置,工作目录中的文件仍然保持不变,所有修改都处于暂存状态。你可以直接重新提交这些内容:

    git commit -m "Your commit message"
    

  4. 强制推送(如果你在一个远程分支上工作且已经推送过): 如果你已经推送到远程分支,可能需要强制推送:

    git push --force
    

这样操作之后,第二次 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

$ git checkout -b iss53
Switched to a new branch "iss53"

它是下面两条命令的简写:

$ git branch iss53
$ git checkout iss53

从某个commit分支

git checkout commitId -b 本地新branchName 

拉远端新分支下来

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

本地覆盖远端某分支

git push origin develop:master
or, more generally
$ git push <remote> <local branch name>:<remote branch to push into>

正常切换

git checkout iss53

分支上提交

git push origin xxx (xxx为要提交代码的分支名称)

分支historypull

git rebase master
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 命令来达到上述目的:

$ git checkout master
$ git merge hotfix

想要合并的分支 hotfix 所指向的提交 C4 是你所在的提交 C2 的直接后继, 因此 Git 会直接将指针向前移动。换句话说,当你试图合并两个分支时, 如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候, 只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。

情况2:解决diverged分歧

你的开发历史从一个更早的地方开始分叉开来(diverged)。 因为,master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4 和 C5)以及这两个分支的公共祖先(C2),做一个简单的三方合并。

手动解决分歧

git merge //冲突后
git status //显示unmerged的结果

文件格式如下:

<<<<<<< HEAD:index.html
a-----------balabala------------
=======
b-----------balabala------------
>>>>>>> iss53:index.html

只需要修改成想要的,然后 git add。git就会认为git冲突已经被处理。

最好使用 git commit来提交,message应该是默认的 Merge branch 'iss53'

删除

git branch -d hotfix

参考文献

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