0%

Git-从入门到精通

Git Bash的简单使用方法。

git 可以分三个区:

工作区(注解编辑页面),就是本地文件夹。
暂存区(数据暂时存放的位置,可以在工作区和版本库之间进行数据的友好交流),git add 命令将他们添加到暂存区。
版本库/本地仓库(存放已经提交的数据,push的时候,就是将这个区的数据push到远程仓库了),git commit 命令则将暂存区中的文件提交到本地仓库中。

首先连接到国际互联网:

1
2
3
# 不需要的就不用了
export http_proxy="http://127.0.0.1:1080/"
export https_proxy="http://127.0.0.1:1080/"

创建代码仓库

1
2
3
4
5
6
git config --global user.name "SAKURA"
git config --global user.email "xxx@gmail.com"
# 建立代码仓库(在指定目录建立.git文件夹)
git init
# 查看代码仓库状态
git status

提交本地代码

1
2
3
4
5
6
7
8
9
git add READEME.txt
# 全部更新到暂存区
git add .
# 在 -m 后面加上声明, 将代码提交到本地仓库
git commit -m "Wrote a READEME file"
# 如果要求的提交备注特别多,可以打开一个vi编辑器
git commit
# 从本地仓库提交到远程仓库master分支
git push -u origin master

注释
可以在代码仓库的根目录下创建一个名为.gitignore的文件,然后编辑里面的内容,把不需提交的文件忽略掉!

commit前的文件状态

git status查看文件状态,Git在未进行commit操作之前,存在三种状态:

Untracked files

Changes not staged for commit

Changes to be committed

分支的建立

早建分支, 多用分支

1
2
3
4
5
6
# 建立分支
git branch newImage
# 切换到新分支 newImage
git checkout newImage;
# 新分支代码提交
git commit

上面的操作可以简化为下面两步

1
2
3
4
# 创建新的分支并切换到新分支
git checkout -b newImage
# 新分支代码提交
git commit

分支的合并

方法一:Merge

1
2
3
4
5
6
7
8
9
10
11
12
# 建立新的分支bugFix
git branch bugFix
# 切换到bugFix分支
git checkout bugFix
# bugFix代码提交
git commit
# 切换到master分支
git checkout master
# master分支代码提交
git commit
# 分支合并 - 现在master分支上有了bugFix的提交
git merge bugFix

方法二:Rebase
简单来说Rebase就是取出一系列的提交记录,“复制”它们,然后在另外一个地方逐个将修改放下去,这样的好处是会使代码库的提交历史变得清晰。

1
2
3
4
5
6
# 假设当前是在bugFix分支下,将bugFix分支的工作直接移动到master分支上
git rebase master
# 切换到master分支
git checkout master
# 将master分支的引用向前移动,即rebase到bugFix
git rebase bugFix

在提交树上移动

HEAD 总是指向当前分支上最近一次提交记录,HEAD通常是指向分支名的,但是可以通过git checkout <哈希值>来将HEAD指向一个具体的提交记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看HEAD指向的两种方式
cat .git/HEAD
# 如若HEAD指向的是一个引用
git symbolic-ref HEAD
# 分离的HEAD,为了让其指向某个具体的提交记录而不是分支名 注:这里的Hash值并不需要全部40位,
# 能表示出唯一标识的前7位字符就可以
git checkout <提交记录的哈希值>
````
为了避免使用`git log`命令查看Hash值,再通过`git checkout`命令分离HEAD,所以有了**相对引用**
> `^` 表示向上移动一个提交记录
```shell
git checkout HEAD^
# 或者
git checkout master^

~<num>表示向上移动多个提交记录, num为1时等价与^

1
2
3
4
# 寻找指定提交记录的父提交
git checkout HEAD~3
# 或者
git checkout master~3

相对引用最常见的地方就是用来移动分支

1
2
# 将master分支移到HEAD所指分支位置前三个节点
git branch -f master HEAD~3

撤销变更

方法一:git reset - 仅限在本地分支中使用

1
2
3
# 把分支记录回退几个提交记录来实现撤销改动,最新的提交变成了未加入暂存区状态(git reset 缺省为 git reset --soft)即文件没有更改
# 只是将git commit 的信息给回退了。推荐直接使用 git reset --hard HEAD^, --hard参数会将文件直接修改回去。
git reset HEAD~1

方法二:git revert - 适用于提交到了远程分支

1
2
# 会在远程添加一个新的提交记录,用来抵消掉远程仓库最新的更改
git revert HEAD

但是如果你后悔了怎么办。这个时候需要

1
2
3
4
# 查看所有版本号
git reflog
# 退回到指定版本 包括已经删除了的修改
git reset --hard XXX<版本号>

提交记录的整理

将一些提交复制到当前所在的位置(HEAD)的下面,cherry-pick 可以将提交树上任何地方的提交记录取过来追加到 HEAD上(只要不是HEAD上游的提交就没有问题)

1
2
# git cherry-pick <提交号>...
git cherry-pick d4b052 4aa0aa

交互式的rebase

你可以通过给git rebase增加-i选项来以交互方式地运行rebase。你必须通过告诉命令衍合到哪次提交,来指明你需要重写的提交的回溯深度。

Git_git_log

1
2
# 这是一个衍合命令——HEAD~2..HEAD范围内的每一次提交都会被重写,无论你是否修改说明。
git rebase -i HEAD~2

上述命令会打开一个交互窗口:

Git-从入门到精通_git_rebase_-i

很重要的一点是你得注意这些提交的顺序与你通常通过log命令看到的是相反的。

通过rebase UI界面, 你能做3件事:

  • 调整提交记录的顺序
  • 删除你不想要的提交
  • 合并提交, 把多个提交记录合并成一个。

详情请看这里

查看修改的内容

1
2
3
4
# "+"号表示新增内容, "-"号表示删除的内容
git diff
# 可视化的查看方法
git difftool

查看提交记录

1
git log
  • 此次提交对应的版本号
  • 提交人:姓名 邮箱
  • 提交的时间
  • 提交版本修改的内容:就是我们commit -m “xxx”里的xxx

记住密码

1
git config --global credential.helper store

版本回退

提交后回退到上一个版本

  • 需要版本号
  • HEAD代表当前版本, HEAD^表示上一个版本, 以此类推
1
2
3
4
5
6
7
# 查看版本号
git log
git reset --hard f37911a60ca123c86c712ff0539619902a7375e8(目标版本号)

git reset --hard HEAD
git reset --hard HEAD^
git log

如果你又后悔了

1
git reflog

键入版本号

1
git reset --hard 版本号(你要回退的版本号)

又会回到你期望的版本!

GitHub 初始化提交

  • create a new repository on the command line
    1
    2
    3
    4
    5
    6
    7
    echo "# NOTES" >> README.md
    git init
    # git add .
    git add README.md
    git commit -m "first commit"
    git remote add origin https://github.com/XXX/NOTES.git
    git push -u origin master
  • push an existing repository from the command line
    1
    2
    git remote add origin https://github.com/XXX/NOTES.git
    git push -u origin master

自动上传脚本:

1
2
3
4
5
6
7
8
9
#! /bin/bash
echo 'start autodeployment...:)'
hexo clean
echo 'hexo clean over...'
hexo generate
echo 'hexo generate over...'
hexo deploy
echo 'hexo deploy over...'
echo 'run success!:)'

常用操作

场景:本地新建了一个新的文件夹,想拉取远程的一个项目

1
2
3
4
5
6
7
git init
git remote add origin https://github.com/XXX/NOTES.git
# git pull <remote> <branch> 直接指定远程master
git pull origin master
# 先指定本地master到远程的master,然后再去pull
git branch --set-upstream-to=origin/master master
git pull

场景:将本地的.git文件删除了,本地文件也更新了,新建git仓库和远程合并

1
2
3
4
5
6
7
8
9
10
11
12
git init
git remote add origin https://github.com/XXX/NOTES.git
# 会报错,failed to push some refs to ...
git push origin master
# 这个时候需要先拉取远程的项目
git pull origin master
# 然后会报错,fatal: refusing to merge unrelated histories
git pull origin master --allow-unrelated-histories
# 然后按照要求解决冲突就好,再commit一下
git add .
git commit -m "fix conflicts"
git push origin master

场景:远程仓库里提交了一些不需要的文件,本地添加到.gitignore文件后不起作用

1
2
3
git rm -r --cached .
git add .
git commit -m 'update .gitignore'

场景:远程仓库有两个分支masterdev,比较二者的版本差异

1
2
3
4
5
6
7
8
9
10
11
12
# 查看远程dev有但是远程master没有的
git log origin/dev ^origin/master
# 查看远程master有但是远程dev没有的
git log origin/dev..origin/master
# 查看远程master有但是远程dev没有的
git log origin/master ^origin/dev
# 查看远程dev有但是远程master没有的
git log origin/master..origin/dev
# 单纯想比较两者之间的区别
git log origin/dev...origin/master
# 或者
git log --left-right dev...master

上述命令可以加上--pretty=oneline让结果输出更简洁。

场景:处理完冲突后将文件查看分支的更改情况

1
2
3
4
5
git log --graph --pretty=oneline --abbrev-commit
# 起别名
git config --global alias.lg “log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit”
# 直接使用
git lg

场景:新建分支并上传,并给分支添加tag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/bin/bash
echo "请输入项目名称"
read project_dir
if [ ! -n "$project_dir" ]
then
project_dir="/"
fi
echo "cd ./$project_dir"
cd ./$project_dir
git init
echo "git init"
git add .
echo "git add ."
git commit -m "R16.40"
echo "git commit -m "R16.40""
echo "请输入仓库地址"
read repository_url
if [ ! -n "$repository_url" ]
then
echo "仓库地址不正确"
fi
git remote add origin $repository_url
echo "git remote add origin $repository_url"
git checkout -b R16.40
echo "git checkout -b R16.40"
git push -u origin R16.40:R16.40
echo "git push -u origin R16.40:R16.40"
echo "请输入tag"
read project_tag
if [ ! -n "$project_tag" ]
then
echo "项目标签不正确"
fi
git tag $project_tag
echo "git tag $project_tag"
git push origin $project_tag
echo "git push origin $project_tag"
echo "代码上传成功"
sleep 5s