Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

Yveltals Blog

基本操作

  • 创建分支
    • git checkout -b name 创建并转到分支
    • git checkout -b dev_1 origin/dev_1 拉取远程分支创建本地
  • 删除分支
    • git branch -d name 删除本地分支
    • git push origin --delete name 删除远程分支
    • git remote prune 远程分支删除后,本地分支同步
  • 关联远端分支
    • git branch -u origin/dev_mz 关联远程分支
    • git branch -vv 查看本地分支与远端分支关联关系
  • 提交到远端
    • git push -u origin dev_mz 推送dev_mz分支到远端并创建关联
  • 查看状态
    • git status -s 查看当前修改、提交状态
    • git diff <file> 比较工作区和暂存区
    • git diff HEAD -- <file> 比较工作区和版本库的最新版本
    • git log -stat显示commit历史及变更文件
  • 合并提交
    • git rebase -i HEAD~N 把最新的N个提交压缩成1个,保留的commit默认pick,丢弃的commit标记fixup
  • 合并分支 & 解决冲突
    • git rebase master 然后按编辑器指示解决冲突
    • git add . 将解决完冲突的文件暂存
    • git rebase --continue 继续rebase,保存commit
    • git push -f 本地rebase完后,由于合并了master几个提交,无法fast-forward,如果该分支仅自己开发,强行push即可

      fast-forward的前提是本地只比远程多了几个最新提交,需要之前的提交记录相同,而rebase后违反了这一点

工作区原理

Git里有三个区域很重要,下图解释了这三个区域的状态的变化过程:

  • HEAD 指向最近一次commit里的所有snapshot
  • Index 缓存区域,只有Index区域里的东西才可以被commit
  • Working Directory 用户操作区域

初始状态

git checkout 的时候,git做了三件事情:

  1. 将 HEAD 指向那个分支的最后一次 commit
  2. 将 HEAD 指向的 commit 里所有文件的 snapshot 替换掉 Index 区域里原来的内容
  3. 将 Index 区域里的内容填充到 Working Directory 里

此时 HEAD、Index、Working Directory 里的内容都是一样的。Index中的内容不是空的,并非只有 git add 后才会有东西。

Changed

如果你在 Working Directory 里修改了文件,则 Working Directory 里的内容和 Index 区域里不一致了。

这个时候git status的结果是:Changes not staged for commit

Staged

一个文件仅仅 changed 是不能被 commit 的,Git 要求只能提交 Index 里的东西。

所以需要 git add。这个命令的意思是,把 Changed 的文件的内容同步到 Index 区域里。这样 Working Directory 和 Index 区域的内容就一致了。这个过程被称之为 stage

这个时候git status的结果是:Changes to be committed

Committed

最后通过 git commit 提交后,HEAD 的状态和 Index 以及 Working Directory 就形成一致了。


撤销操作

区别 reset 和 revert

  • git reset 是会修改版本历史的,即丢弃掉一些版本历史
  • git revert 是根据那个commit逆向生成一个新的commit,版本历史是不会被破坏的。

reset

1. 用于file

1
git reset HEAD <file>

撤销add操作,把文件从index退回workspace,并将更改保存在workspace中

2. 用于commit

1
2
3
git reset HEAD^^  #回退到上上个版本
git reset HEAD~2
git reset d130664a3e6da2d2478f3c6eee8e9dc67a61b1c2

撤销commit操作,必须是未被提交到remote的改动。除了移动当前分支的HEAD,还可以更改workspace和index:

  • --soft:修改HEAD,不修改index和workspace
  • --mixed:修改HEAD和index,不修改workspace,默认
  • --hard:修改HEAD、index、workspace

已经push到远程仓库的commit不允许reset,只能用revert。如果commit已经被push到远程仓库上了,也就意味着其他开发人员就可能基于这个commit形成了新的commit,这时你去reset,就会造成其他开发人员的提交历史莫名其妙的丢失,或者其他灾难性的后果。

checkout

1. 用于file

1
git checkout HEAD <file>

清除文件在workspace的修改,类似于 git restore file

2. 用于commit

1
2
git checkout b4f2fa40955cc34f441466f820b1b84350a31491   # 分离HEAD模式,HEAD可以不指向main等
git checkout main

只是移动HEAD到不同的commit,如果有unstaged的文件,git会阻止操作并提示。

checkout会修改HEAD的指向,变更Index区域里的内容,修改Working Directory里的内容。

这看上去很像 reset --hard,但和 reset --hard 相比有两个重要的差别

  1. reset会把working directory里的所有内容都更新掉
  2. checkout不会去修改你在Working Directory里修改过的文件
  3. reset把branch移动到HEAD指向的地方
  4. checkout则把HEAD移动到另一个分支

对于第二个区别:假设两个分支master和develop 指向不一样的commit,现在在develop分支上(HEAD指向)

  • 如果 git reset master,那么develop就会指向master所指向的那个commit。
  • 如果 git checkout master,那么develop不会动,只有HEAD会移动指向master。

revert

1
git revert HEAD   #revert该版本的修改,相当于 git reset HEAD^

通过新建一个commit来撤销一次commit所做的修改,是一种安全的方式,并没有修改commit history。


密钥与Config配置

SSH key

  1. 创建密钥 ssh-keygen -t ed25519
  2. 查看密钥 cat ~/.ssh/xxx
  3. 添加密钥 Settings -> SSH and GPG keys -> New SSH key
  4. 确定一下ssh-key是否添加成功 ssh -T git@github.com

Config

全局/仓库配置(–global/local)

1
2
3
4
5
6
7
8
9
10
git config --global -l
git config --global core.editor vim
git config --global init.defaultBranch main
git config --global --add pull.rebase true
git config --global user.name "YOURUSERNAME"
git config --global user.email "YOUREMAIL"
git config --global http.proxy http://127.0.0.1:xxxx
git config --global https.proxy http://127.0.0.1:xxxx
# 取消配置
git config --global --unset http.proxy

配置别名,在 .gitconfig 中加入

1
2
[alias]  
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

重新关联远程仓库

  1. 查看远程仓库的链接方式,将http方式改成git方式 git remote show origin

  2. 移除现有的http方式的远程仓库 git remote rm origin

  3. 重新添加成git@github.com的方式并关联

    1
    2
    git remote add origin git@github.com:Yveltals/test.git
    git push -u origin main

HTTPS Auth failed

1
2
3
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://*****-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://***/'

Github 对密码认证的支持于 2021年8月13 日被删除,需要使用个人访问令牌代替。

  • Username: 注册 Github 的邮箱
  • Password: github.com/settings/tokens 页面的 Personal access tokens

在线演示

https://learngitbranching.js.org/?locale=zh_CN