Skip to main content

4 posts tagged with "git"

View All Tags

Git 常用命令

1. Set up 仓库

  • 查看remote是哪个:git remote -v
  • 更换远程仓库: git remote set-url origin xxx
  • 移除远程仓库: git remote remove origin
gitOne min read

[toc]

前言

本系列文章是针对计算机经典书籍《Git 权威指南》的精简版学习笔记,方便大家快速了解内容以及速记,欢迎订阅

上一篇文章,我们学习了创建版本库的几个命令,不熟悉的同学可以参考 Git初始化

  • git log --stat
  • 可以看到每次提交的文件变更统计

5.1 修改不能直接提交吗

  • echo "Nice to meet you" >> welcome.txt
  • git diff
  • 可以看到修改后的文件与本库(与本地比较的不是版本库中的文件,而是一个中间状态的文件)中的文件的差异
  • 工作区与提交任务中相比的差异

diff --git a/welcome.txt b/welcome.txt

index 18832d3..9c2a787 100644

--- a/welcome.txt

+++ b/welcome.txt

@@ -1 +1,2 @@

Hello.

+Nice to meet you

  • 如果此时认为文件修改后可以直接提交,那就错了哦,
  • 尝试运行命令:git commit -m "Append a nice line."
  • 发现会运行不成功
  • 提交日志里面没有新的提交记录出现
  • 执行 git diff 可以看到和之前一样的结果,说明没有提交成功
  • git status查看文件状态,可以看到文件处于修改状态,
  • 精简模式 git status -s

➜ git commit -m "Append a nice line."

On branch master

Changes not staged for commit:

modified: welcome.txt

no changes added to commit

  • 所以如果想提交,需要利用 git add命令
  • git add welcome.txt
  • git diff HEAD
  • 工作区与HEAD相比
  • git diff --stagedgit diff --cached
  • 提交暂存区与版本库中文件的差异
  • git status -s
  • M位于第一列的含义
  • M welcome.txt
  • 版本库中的文件与处于中间状态--提交任务(提交暂存区,stage)中的文件相比有改动
  • M位于第二列的含义
  • 工作区当前的文件与处于中间状态--提交任务(提交暂存区,stage)中的文件相比有改动
  • M welcome.txt
  • 如果此时继续修改welcome.txt 文件
  • echo "Bye-Bye." >> welcome.txt
  • git status -s
  • MM welcome.txt
  • 不但版本库中最新提交的文件与处于中间状态--提交任务(提交暂存区,stage)中的文件相比有改动,而且工作区当前的文件处于中间状态--提交任务(提交暂存区,stage)中的文件相比也有改动
  • 现在再来提交
  • git commit -m "which version checked in?"
  • 如何证明提交成功呢
  • git log --pretty=oneline
  • git status -s
  • git diff

5.2 理解Git暂存区(stage)

  • git status 原理
  • 先依据.git/index文件中记录的时间戳,长度等信息判断工作区文件是否改变
  • 如果工作区文件的时间戳改变了,说明文件的内容可能改变了,需要打开文件,读取文件内容,与源文件做比较,
  • 如果文件内容没有改变,则将该文件新的时间戳记录到.git/index文件中
  • 使用时间戳,文件长度等信息进行比较要比通过文件内容比较要快得多
  • .git/index
  • 实际是一个包含文件索引的目录树,像一个虚拟的工作区
  • 记录了文件名和文件的状态信息(时间戳和文件长度,文件的内容没有存储在其中,而是保存在Git对象库.git/objects目录中

img

  • HEAD实际是指向master分支的一个 “游标”,所以图示的命令中出现HEAD的地方可以用master来替换
  • 图中的objects标识的区域为Git的对象库,实际位于 .git/objects 目录下,这一点会在后面的章节中重点介绍
  • 当对工作区修改(或新增)的文件执行git add命令时,暂存区的目录树将会被更新,同时工作区修改(或新增)的文件内容会被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中
  • 当执行提交操作(git commit)时,暂存区的目录树会写到版本库(对象库)中,master分支会做相应的更新,即master最新指向的目录树就是提交时原暂存区的目录树
  • 当执行git reset HEAD 命令时,暂存区的目录树会被重写,会被master指向的目录树所替换,但是工作区不受影响
  • 当执行git rm --cached <file> 命令时,会直接从暂存区删除文件,工作区则不做出改变
  • 但执行git checkout ., 或git checkout -- <file> 命令时,会用暂存区全部的文件或制定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动
  • 但执行git checkout HEAD . 或git checkout HEAD <file> 命令时,会用HEAD指向的master分支中的全部或者部分文件替换暂存区和工作区中的文件,这个命令也是极具危险性的,因为不但会清除工作区中的未提交的改动,也会清除暂存区中未提交的改动

5.3 Git Diff魔法

1. 工作区,暂存区和版本库的目录树浏览

➜ git ls-tree -l HEAD

100644 blob 7e12803b85898fd0ae42d0a793c3eaf9f0cdd66e 28 test.ini

100644 blob 9c2a787a930a7b547abdf71e47ab1a67de890832 24 welcome.txt

  • -l 参数可以显示文件的大小
  • 第一个字段是文件的属性(rw-r--r--)
  • 第二个字段说明是Git对象库中的一个blob对象(文件),
  • 第三个字段则是该文件在对象库中对应的ID--一个40位的SHA1哈希值格式的ID
  • 第四个字段是文件大小
  • 第五个字段是文件名
  • 清除当前工作区中没有加入版本库的文件和目录(非跟踪文件和目录)
  • git clean -fd
  • 用暂存区内容刷新工作区
  • git checkout .
2. Git diff 魔法

img

  • 工作区和暂存区比较
  • git diff
  • 暂存区和HEAD比较
  • git diff --cached
  • 工作区和HEAD比较
  • git diff HEAD

5.4 不要使用git commit -a

  • 好处
  • 减少用git add 命令标识变更文件的步骤
  • 坏处
  • 丢掉Git暂存区带给用户的最大好处:对提交内容进行控制的能力
5.5 搁置问题,暂存状态
  • git stash
  • 保存当前共奏进度
Git6 min read

[toc]

前言

本系列文章是针对计算机经典书籍《Git 权威指南》的精简版学习笔记,方便大家快速了解内容以及速记,欢迎订阅

4.1 创建版本库及第一次提交

  1. 首先查看自己的git版本
  • git --version
  • 比如我的是 git version 2.24.3 (Apple Git-128)
  1. 建立新工作目录
  • 如果git版本是1.6.5+
  • git init demo
  • 否则就一步一步来
  • mkdir demo
  • cd demo
  • git init
  1. 查看隐藏的git目录
  • ls -aF
  • 会显示 ./ ../ .git/
  • 其中 .git 就是Git版本库(又叫仓库,repository)
  • 版本库所在目录称为工作区,比如我的 ~/coding/git/demo
  1. 为工作区加内容
  • echo "Hello." > welcome.txt
  • 需要运行命令 git add welcome.txt将新建立的文件添加到版本库
  • 提交:git commit -m "initialized."
  • -m 为提交说明
  • [master (root-commit) 1a557fb] initialized. 从这可以看出此次提交在名为master分支上,且是该分支的第一个提交(root-commit),提交ID为1a557fb
  • 1 file changed, 1 insertion(+)可以看出此次提交修改了一个文件,包含一行的插入
  • create mode 100644 welcome.txt 可以看出此次提交创建了一个新文件

4.2 思考:为什么工作区根目录下有一个.git目录

  • Git及其他分布式版本控制系统(如Mercurial/Hg, Bazaar)的一个共同特点是版本库位于工作区的根目录下
  • 传统的集中式版本控制系统需要建立版本库和工作区的对应
  • Git的设计是的所有的版本控制操作都在本地即可完成
  • Git提供了一条命令用来搜索工作区的文件内容
  • git grep "Hell"
  • 结果是 welcome.txt:Hello.
  • 如果在工作区的子目录中执行Git命令
  • 会在工作区目录中依此向上递归查找git目录,找到的.git目录就是工作区对应的版本库,.git所在的目录就是工作区的根目录,文件.git/index记录了工作区文件的状态(实际上是暂存区的状态)
  • 在非工作区执行git命令时会因为找不到.git目录而报错
  • 如果想知道工作区的根目录的位置
  • 先创建多级目录并进入
  • mkdir -p a/b/c
  • cd a/b/c
  • 当前目录:~/coding/git/demo/a/b/c
  • 显示版本库.git目录所在的位置
  • git rev-parse --git-dir
  • /Users/xujie/coding/git/demo/.git
  • 显示工作区根目录
  • git rev-parse --show-toplevel
  • /Users/xujie/coding/git/demo
  • 显示工作区根目录的相对目录
  • git rev-parse --show-prefix
  • a/b/c/
  • 显示从当前目录后退到工作区的根的深度
  • git rev-parse --show-cdup
  • ../../../

4.3 git config命令的各参数有何区别

  • 使用不同参数的git config命令时机操作了不同的文件
  • git config -e
  • 实际上操作 ./demo/.git/config (版本库级别,优先级最高)
  • git config -e --global
  • 实际上操作: ~/.gitconfig (用户全局配置)
  • git config -e --system
  • 实际上操作 /etc/gitconfig (系统级别)
  • git配置文件采用的是INI 文件格式
  • cat .git/config

[core]

repositoryformatversion = 0

filemode = true

bare = false

logallrefupdates = true

ignorecase = true

precomposeunicode = true

  • 读取配置文件的属性
  • git config <section>.<key>
  • git config core.bare
  • false
  • 更改或者设置INI文件中某个属性的值
  • git config a.b something
  • git config x.y.z something

$ cat .git/config

[core]

repositoryformatversion = 0

filemode = false

bare = false

logallrefupdates = true

symlinks = false

ignorecase = true

[a]

b = something

[x "y"]

z = something

  • 操作任何其他的INI文件
  • GIT_CONFIG=test.ini git config a.b.c.d "hello, world"

$ cat test.ini

[a "b.c"]

d = hello, world

  • 从配置文件test.ini中读取配置
  • GIT_CONFIG=test.ini git config a.b.c.d
  • hello, world

4.4 思考:是谁完成的提交

  • 可以通过执行下面的命令删除user.name 和 user.email的配置
  • git config --unset --global user.name
  • git config --unset --global user.email
  • 然后提交
  • git commit --allow-empty -m "who does commit?"

[master df2b623] who does commit?

Committer: xujie <xujie@xujies-MacBook-Pro.local>

Your name and email address were configured automatically based

on your username and hostname. Please check that they are accurate.

You can suppress this message by setting them explicitly:

git config --global user.name "Your Name"

git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

git commit --amend --reset-author

1 file changed, 2 insertions(+)

create mode 100644 test.ini

  • git log --pretty=fuller

commit df2b62367ca80056d248113aed8f3dd4d10dcdca (HEAD -> master)

Author: xujie <xujie@xujies-MacBook-Pro.local>

AuthorDate: Wed Sep 28 22:37:49 2022 +0800

Commit: xujie <xujie@xujies-MacBook-Pro.local>

CommitDate: Wed Sep 28 22:37:49 2022 +0800

who does commit?

commit 1a557fb84b2ed006bca7395729b1efb71baf96f1

Author: jiexu <admin@example.com>

AuthorDate: Wed Sep 28 21:39:06 2022 +0800

Commit: jiexu <admin@example.com>

CommitDate: Wed Sep 28 21:39:06 2022 +0800

initialized.

  • 重新配置提交者信息
  • git config --global user.name "jiexu"
  • git config --global user.email jiexu@example.com
  • 重新提交修改
  • git commit --amend --allow-empty --reset-author

4.5 思考:随意设置提交者姓名,是否不太安全

  • 这是分布式版本控制系统的特性使然,每个人都是自己的版本库的主人,很难也没有必要进行身份认证,所以无法使用经过认证的用户名作为提交的用户名

备份本章的工作

  • 备份内容
  • git clone demo demo-step-1
Git5 min read

* git fetch --tags --progres
* git rev-parse
* git config core.sparsecheckout
* git checkout -f
GitOne min read