git操作从0到1

444 阅读8分钟

基础概念

文件的三种状态及其对应的工作区域

  • 已修改(被修改的文件) 工作目录
  • 已暂存(等待被提交的文件) 暂存区
  • 已提交(提交到本地仓库的文件) git仓库

下图演示了三种状态以及对应的工作区域

基本命令

    1. git init 初始化创建仓库, 会创建出一个隐藏的git文件夹,所有操作历史放在里面
    1. git add 将文件添加到暂存区 可add多个文件 git add a.txt b.txt
    1. git add . 添加所有改动文件及未追踪文件
    1. git log 查看日志文件
    1. clear清空命令
    1. git中文乱码解决,右键options => text => ZH_CN UTF-8。文件名乱码输入 git config --global core.quotepath false
    1. mkdir新建文件夹,touch新建文件(windows)

提交文件

    1. git commit 提交文件

    • vim编辑器描述文件,i键切换到输入模式,按esc后再按两个大写z退出

    • 或者按esc ,按:再输入wq按回车

    1. git commit -a -m ‘描述’ 合并提交和描述,从工作区提交到暂存区后,直接提交(也要用add进行跟踪)
    1. git commit -m ‘描述’ 合并提交和描述,一步完成操作

删除文件

    1. git rm 删除文件,并不保留在工作目录(修改后的文件还没commit,不可删除)
    1. git rm --cache 删除文件,只是删除git本地仓库的文件,保留在工作目录
    1. git rm -f 强制删除,不建议用

移动文件

    1. git mv a.txt first/a.txt 移动a.txt文件到first文件下面(commit可以看到rename a.txt => first/a.txt) 移动文件的本质其实是重命名。
  • 2.重命名

    • mv file_from file_to

    • git rm file_from

    • git add file_to 相当于git mv file_before file_after

查看文件状态

1.git status 查看文件状态

2.git status -s 查看文件状态简化情况

  • ??未追踪文件
  • A 添加到暂存区
  • M被修改但未放入暂存区 (M前面是空格)
  • MM修改后放入暂存区,并且又再次被修改
  • M 被修改后放入暂存区(M后面是空格)
  • D 删除文件
  • R 移动文件(重命名)

查看命令

git diff(比较差异)
    1. git diff 显示对比工作目录与暂存区和仓库的内容差异信息
    1. git diff -- staged 显示对比暂存区与仓库的内容差异信息

git log

信息太长的话,按q键退出

  • git log -p 打印最近一条的详细信息

  • git log -n 打印最近n条的详细信息

  • git log --stat 列出所有被修改的文件,以及简略的统计信息

  • git log --decorate --oneline 查看历史记录的简洁的版本

提交对象

git保存的并不是文件的变化或差异,而是一系列不同时刻的文件快照。

提交操作时git会保存一个提交对象,该对象中包含一个指向暂存内容的快照,作者姓名,邮箱,父对象指针以及提交输入信息。

  • 首次提交没有父对象
  • 普通提交有一个父对象
  • 多个分支合并有多个父对象

master分支

git分支本质上是指向提交对象的可变指针,master分支是get init命令默认创建的,它会在每一次提交中自动前移,它和其他分支没有区别。

HEAD是一个特殊指针,它是唯一的,它指向当前所在分支

  • 创建分支:git branch 分支名称

  • 创建分支并切换到该分支:git checkout -b 分支名称

  • 切换分支:git checkout 分支名

    • 将HEAD指向切换的分支
    • 将工作目录恢复成当前分支的快照

下图演示了从master分支切换到branch1分支,然后在branch1分支上提交文件,最后回到master分支上提交文件

两个查看分支情况好用命令

git log --decorate --oneline 查看分支情况
git log --decorate --oneline --all --graph 查看所有分支树形情况

合并分支

git merge 目标分支

将目标分支的内容合并到当前分支

合并会会考虑几个元素

  • 共同的父元素
  • 目标分支和当前分支的最新提交节点
  • 进行整合,进行新的提交

快速前移

概念:master分支和目标分支在没有分叉的情况进行合并,不进行提交

缺点:我们不能从日志中看出它进行合并操作。

禁止快速前移:git merge --no-ff -m '描述信息' 目标分支

分支冲突

master和branch1在同一commit上时(直接级祖先关系),可以直接合并,不会产生冲突。(快速前移)

master和branch1不在同一commit上时,修改同一个文件的内容不一致时会产生冲突,修改一致是空合并。

解决分支冲突:手动解决冲突部分,解决完再提交

删除分支

git branch -d 分支名称(没有合并的分支不能删除)

强制删除:git branch -D 分支名称

取消合并

git merge --abort

撤销指令集合

  1. git rm --cache 文件名 撤销已暂存

  2. git checkout -- 文件名 撤销已修改

  3. git reset HEAD 文件名 撤销已暂存

  4. git reset HEAD^ 撤销上一个操作

  5. git reset HEAD~5 撤销5次操作

  6. git reflog 查看历史提交

  7. 修改描述:git commit -m '新描述' --amend

  8. 合并提交 git commit -- amend

Reset的本质:可以用来撤销commit操作(取消暂存),但实质上不是撤销操作,而是移动HEAD并且带上所指向的分支,重置HEAD及分支。该被撤销的提交并未丢失,可以通过哈希找回(git reset 哈希值)

  • git reset --hard 避免使用,会重置工作目录,丢失暂存区
  • git reset --mixed(默认使用)保留工作目录,清空暂存区
  • git reset --soft 保留工作目录,将原分支差异放到暂存区

图示Reset本质

checkout:撤销对文件的修改,只会改变HEAD指向,并不会影响分支。

图示checkout不会影响分支

存储

当在分支a中向暂存区添加内容,切换到分支b的时候,提交commit会带上分支a的暂存中的内容。为了避免分支b提交分支a中暂存区的内容。

存储使用情景:一般就是当你在b分支暂存区添加文件,又不希望它提交,切换到a分支前进行存储操作。

  • git stash 存储 暂存区及工作目录未修改文件

  • git stash -u 存储 暂存区及工作目录未修改文件以及未追踪文件

  • git stash list 打印所有存储内容

  • git stash apply 将存储内容重新应用(默认不保留已暂存内容)

  • git stash apply --index 将原暂存内容依旧以暂存进行取出

  • git stash drop 移出存储

rebase变基

rebase命令和merge一样,也是进行合并操作的,rebase命令将一个分支的内容移到另外一个分支。

工作流程:

  1. 首先找到两个分支的共同祖先
  2. 然后对比当前分支与祖先的历次提交,进行提取相应修改,并保存为临时文件,将当前分支指向目标基底,最后将刚刚保存的临时文件依序应用。

图解rebase变基

  • 没有变基前有两个分支

  • 改变HEAD指向

  • 找到共同祖先,对比当前分支与祖先的历次提交,进行提取相应修改,并将c3,出c4保存为临时文件C6,C7,将当前分支指向目标基底,最后将刚刚保存的临时文件依序应用。

  • 改变HEAD指向:

  • 执行merge命令,快速前移:

git的别名设置

将checkout命令别名设为co

git config --local alias.co checkout

github提交

多人合作模式

中央仓库:存储每个成员的提交对象,共享提交对象给每个成员。而我们开发中常用到的中央仓库就是非常出名的github。

忽略文件(上传github时忽略掉的文件)

touch .gitignore 新建 .gitignore 文件

  • # 该行会被忽略
  • ** 表示匹配任意中间目录
  • * 表示匹配零个或多个任意字符
  • !表示忽略文件以外的文件或目录
  • [abc] 匹配任意一个在方括号内的字符
  • [0 - 9] 在这范围的都可以匹配
  • ?只匹配任意字符

例如忽略dist目录:/dist/ 忽略.doc问价:*.doc

tag标签

github经常能看到“xx版本”,这个“xx版本”就是标签。

  • 设置标签:git tag v1.0
  • 查看标签:git tag
  • 给某一个commit打tag,先用git log --online查看commit哈希值,再执行 git tag v1.0 '哈希值'
  • 给tag标签添加描述信息:git tag -a v1.0 -m '描述信息' '哈希值'
  • 查看tag的描述信息:git show v1.0
  • 删除标签:git tag -d v1.0

远程仓库

  • git push 提交远程仓库
  • git clone 克隆项目到本地
  • git pull 拉取

提交分支

  • 提交master分支:git push -u origin master
  • 提交其他分支:git push -u origin '分支名'

远程仓库克隆分支(拉取下来的分支默认是master)

  • git checkout -b branch1 orign/branch1

删除远程仓库分支:

  • git push origin :branch

推送标签到远程仓库:

  • git push orgin v1.0
  • git push orign --tags

删除远程仓库的标签:

  • git push orgin :refs/tags/v1.0

使用ssh

自己电脑cmd执行:ssh-keygen -t rsa -C "用户名"。执行命令后找到.ssh文件所在位置,找到pub后缀的文件,复制文件里的密钥内容,填写到key的位置

建议

主分支上尽量不进行操作, 新建开发分支进行开发。