git初入门(二):文件操作

2023-09-16 21:52:18 浏览数 (1)

git初入门(二):文件操作

篇幅较长,可收藏防止迷路

0. 文件的四种状态

  • Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到 git 库, 不参与版本控制. 通过git add 状态变为Staged.
  • Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件
  • Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改
  • Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存, 文件状态为Modified

1. git init

代码语言:javascript复制
 # 在当前目录新建一个Git代码库
 git init
 # 新建一个目录,将其初始化为Git代码库
 git init [project-name]

2. git clone

代码语言:javascript复制
 # 克隆一个项目和它的整个代码历史(版本信息)
 git clone [url]

3. git status(查看文件状态)

代码语言:javascript复制
 #查看指定文件状态
 git status [filename]
 #查看所有文件状态
 git status

4. git add(添加文件与目录)

代码语言:javascript复制
 # 添加指定文件到暂存区
 $ git add [file1] [file2] ...
 
 # 添加指定目录到暂存区,包括子目录
 $ git add [dir]
 
 # 添加当前目录的所有文件到暂存区
 $ git add .

6. git reset

代码语言:javascript复制
 #如果已经用add 命令把文件加入stage了,就先需要从stage中撤销
 git reset HEAD <file>...

7. git clean

代码语言:javascript复制
 # 移除所有未跟踪文件
 # 一般会加上参数-df,-d表示包含目录,-f表示强制清除。
 git clean [options]

8. git rm(移除文件与目录)

代码语言:javascript复制
 #只从stage中删除,保留物理文件
 git rm --cached readme.txt 
 
 #不但从stage中删除,同时删除物理文件
 git rm readme.txt 
 
 #把a.txt改名为b.txt
 git mv a.txt b.txt

9. git diff(查看文件修改后的差异)

代码语言:javascript复制
 #查看文件修改后的差异
 git diff [files]
 
 ---a 表示修改之前的文件,   b 表示修改后的文件
 
 #比较暂存区的文件与之前已经提交过的文件
 git diff --cached

10. git checkout(签出)

代码语言:javascript复制
 #用法一
 git checkout [-q] [<commit>] [--] <paths>...
 #用法二
 git checkout [<branch>]
 #用法三
 git checkout [-m] [[-b]--orphan] <new_branch>] [<start_point>]
 
 $ git checkout branch
 #检出branch分支。要完成图中的三个步骤,更新HEAD以指向branch分支,以及用branch  指向的树更新暂存区和工作区。
 
 $ git checkout
 #汇总显示工作区、暂存区与HEAD的差异。
 
 $ git checkout HEAD
 #同上
 
 $ git checkout -- filename
 #用暂存区中filename文件来覆盖工作区中的filename文件。相当于取消自上次执行git add filename以来(如果执行过)的本地修改。
 
 $ git checkout branch -- filename
 #维持HEAD的指向不变。用branch所指向的提交中filename替换暂存区和工作区中相   应的文件。注意会将暂存区和工作区中的filename文件直接覆盖。
 
 $ git checkout -- . 或写作 git checkout .
 #注意git checkout 命令后的参数为一个点(“.”)。这条命令最危险!会取消所有本地的  #修改(相对于暂存区)。相当于用暂存区的所有文件直接覆盖本地文件,不给用户任何确认的机会!
 
 $ git checkout commit_id -- file_name
 #如果不加commit_id,那么git checkout -- file_name 表示恢复文件到本地版本库中最新的状态。

如:

代码语言:javascript复制
 $ echo “123”>>hyy.txt
 $ git add hyy.txt
 $ echo "1" >> hyy.txt
 $ git status
 $ git status
 On branch master
 Changes to be committed:
   (use "git restore --staged <file>..." to unstage)
         new file:   hyy.txt
 
 Changes not staged for commit:
   (use "git add <file>..." to update what will be committed)
   (use "git restore <file>..." to discard changes in working directory)
         modified:   hyy.txt
         
 $ git checkout hyy.txt # 取消了第3行的更改,使用暂存区里的hyy.txt覆盖了本地的hyy.txt

11. 忽略文件

有些时候我们不想把某些文件纳入版本控制中,比如数据库文件,临时文件,设计文件等

在主目录下建立 ".gitignore" 文件,此文件有如下规则:

  1. 忽略文件中的空行或以井号(#)开始的行将会被忽略。
  2. 可以使用 Linux 通配符。例如:星号(*)代表任意多个字符,问号(?)代表一个字符,方括号(abc)代表可选字符范围,大括号({string1,string2,...})代表可选的字符串等。
  3. 如果名称的最前面有一个感叹号(!),表示例外规则,将不被忽略。
  4. 如果名称的最前面是一个路径分隔符(/),表示要忽略的文件在此目录下,而子目录中的文件不忽略。
  5. 如果名称的最后面是一个路径分隔符(/),表示要忽略的是此目录下该名称的子目录,而非文件(默认文件或目录都忽略)。

如:

代码语言:javascript复制
 # 
 #为注释
 *.txt #忽略所有 .txt结尾的文件
 !lib.txt #但lib.txt除外
 /temp #仅忽略项目根目录下的TODO文件,不包括其它目录temp
 build/ #忽略build/目录下的所有文件
 doc/*.txt #会忽略 doc/notes.txt 但不包括 doc/server/arch.txt

示例:

代码语言:javascript复制
 # 忽略.log文件
 $ echo "123">f1.log
 $ echo "123">f2.log
 $ echo "123">hyy03.txt
 $ git add .
 warning: LF will be replaced by CRLF in .gitignore.
 The file will have its original line endings in your working directory
 warning: LF will be replaced by CRLF in hyy03.txt.
 The file will have its original line endings in your working directory
 $ git status
 On branch master
 No commits yet
 Changes to be committed:
   (use "git rm --cached <file>..." to unstage)
         new file:   .gitignore
         new file:   hyy00.txt
         new file:   hyy02.txt
         new file:   hyy03.txt

通用的 java 忽视文件:

代码语言:javascript复制
 # Compiled class file
 *.class
 
 # Log file
 *.log
 
 # BlueJ files
 *.ctxt
 
 # Mobile Tools for Java (J2ME)
 .mtj.tmp/
 
 # Package Files #
 *.jar
 *.war
 *.ear
 *.zip
 *.tar.gz
 *.rar
 
 # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
 hs_err_pid*

idea 忽视文件:

代码语言:javascript复制
 .idea/
 *.iml
 out/
 gen/
 idea-gitignore.jar
 resources/templates.list
 resources/gitignore/*
 build/
 build.properties
 junit*.properties
 IgnoreLexer.java~
 .gradle
 /verification

12. git commit(提交)

通过 add 只是将文件或目录添加到了 index 暂存区,

使用 commit 可以实现将暂存区的文件提交到本地仓库。

代码语言:javascript复制
 # 提交暂存区到仓库区
 $ git commit -m [提交说明信息]
 
 # 提交暂存区的指定文件到仓库区
 $ git commit [file1] [file2] ... -m [message]
 
 # 提交工作区自上次commit之后的变化,直接到仓库区,跳过了add,对新文件无效
 $ git commit -a
 
 # 提交时显示所有diff信息
 $ git commit -v
 
 # 使用一次新的commit,替代上一次提交
 # 如果代码没有任何新变化,则用来改写上一次commit的提交信息
 $ git commit --amend -m [message]
 
 # 重做上一次commit,并包括指定文件的新变化
 $ git commit --amend [file1] [file2] ...

□ 提交

条件

代码语言:javascript复制
 $ git status
 On branch master
 No commits yet
 Changes to be committed:
   (use "git rm --cached <file>..." to unstage)
         new file:   .gitignore
         new file:   hyy00.txt
         new file:   hyy02.txt
         new file:   hyy03.txt

提交:

代码语言:javascript复制
 $ git commit hyy00.txt -m "指定提交hyy00.txt"
 [master (root-commit) cbc3543] 指定提交hyy00.txt
  1 file changed, 3 insertions( )
  create mode 100644 hyy00.txt

提交后的状态:

代码语言:javascript复制
 $ git status
 On branch master
 Changes to be committed:
   (use "git restore --staged <file>..." to unstage)
         new file:   .gitignore
         new file:   hyy02.txt
         new file:   hyy03.txt

可以看到已经没有了hyy00.txt

□ 修订提交

如果我们提交过后发现有个文件改错了,或者只是想修改提交说明,这时可以对相应文件做出修改,将修改过的文件通过 "git add" 添加到暂存区,然后执行以下命令:

代码语言:javascript复制
 #修订提交
 $ git commit --amend <文件>

例子:

代码语言:javascript复制
 $ git commit --amend hyy00.txt
 [master f2cda26] dddddd指定提交hyy00.txt
  Date: Sun Nov 28 13:41:42 2021  0800
  1 file changed, 3 insertions( )
  create mode 100644 hyy00.txt

□ 撤销提交(commit)

原理就是放弃工作区和 index 的改动,同时 HEAD 指针指向前一个 commit 对象

代码语言:javascript复制
 #撤销上一次的提交
 git reset --hard HEAD~1
 # HEAD~1 上一次提交的 编号(要通过 git log 查看提交日志,也可直接指定提交编号或序号)
 git reset --hard cbc3543
 
 # 撤销提交
 git revert <commit-id>
 # 这条命令会把指定的提交的所有修改回滚,并同时生成一个新的提交。

13. git log(日志)

查看提交日志可以使用 git log 指令,语法格式如下:

代码语言:javascript复制
 #查看提交日志
 git log [<options>] [<revision range>] [[--] <path>…?]

"git log --graph" 以图形化的方式显示提交历史的关系,这就可以方便地查看提交历史的分支信息,当然是控制台用字符画出来的图形。 "git log -1"则表示显示 1 行。 使用 history 可以查看您在 bash 下输入过的指令。

□ 查看所有分支日志

"git reflog"中会记录这个仓库中所有的分支的所有更新记录,包括已经撤销的更新。

14. git ls-files(查看文件列表)

使用 git ls-files 指令可以查看指定状态的文件列表,格式如下:

代码语言:javascript复制
 #查看指定状态的文件
 git ls-files [-z] [-t] [-v] (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])* (-[c|d|o|i|s|u|k|m])*

例子

代码语言:javascript复制
 $ git ls-files #默认查看所有缓存(已提交的)的文件
 hyy00.txt
 hyy02.txt
 
 $ git ls-files -o # 查看未被跟踪的文件
 
 $ git ls-files -s
 100644 6adbdc28dfd30b8cd6c32480c4c65c261cc0ff72 0       hyy00.txt
 100644 35db16759fb4115448fd06a00b1e076bb527e590 0       hyy02.txt

15.撤销更新

□ 撤销暂存区更新

使用 "git add"把更新提交到了暂存区。

这时"git status" 的输出中提示我们可以通过 git restore --staged <file>..." 把暂存区的更新移出到 WorkSpace 中。

示例:f6 已经提交,工作区修改,暂存区修改,撤销:

代码语言:javascript复制
 $ git add hyy03.txt
 $ git status
 On branch master
 Changes to be committed:
   (use "git restore --staged <file>..." to unstage)
         modified:   hyy03.txt

□ 撤销本地仓库更新

使用 git log 查看提交日志

代码语言:javascript复制
 $ git log
 
 commit afd439252a9af271c493141fe11065a312413cd8 (HEAD -> master)
 Author: 胡宇洋 <2582952862@qq.com>
 Date:   Sun Nov 28 14:50:41 2021  0800
 
     修改hyy04
 
 commit abc3e822acfde1398855919de04c7e8a66f2de52 (HEAD -> master)
 Author: 胡宇洋 <2582952862@qq.com>
 Date:   Sun Nov 28 14:40:10 2021  0800
 
     hyy04.txt首次提交到本地仓库
 
 commit eaed0f7370433ffe6c49e08ad9a172b9abbeaf2d (HEAD -> master)
 Author: 胡宇洋 <2582952862@qq.com>
 Date:   Sun Nov 28 14:21:28 2021  0800
 
     提交hyy03到本地仓库
 
 commit 0424b988aaaf192c7e2580daf15714c01fb085a0
 Author: 胡宇洋 <2582952862@qq.com>
 Date:   Sun Nov 28 13:56:24 2021  0800
 
     提交hyy002.txt到本地仓库,使用amend修订提交。
 
 commit f2cda2644e0da78e163c4e152e1e86dd4fe1e4f3
 Author: 胡宇洋 <2582952862@qq.com>
 Date:   Sun Nov 28 13:41:42 2021  0800
 
     dddddd指定提交hyy00.txt

撤销提交有两种方式:

使用 HEAD 指针使用 commit id

在 Git 中,有一个 HEAD 指针指向当前分支中最新的提交。

当前版本,我们使用 "HEAD^",那么再前一个版本可以使用 "HEAD^^",如果想回退到更早的提交,可以使用 "HEADn"。(也就是,HEAD^=HEAD1,HEAD^^=HEAD~2)

代码语言:javascript复制
 git reset --hard HEAD^
 git reset --hard HEAD~1
 git reset --59cf9334cf957535cb328f22a1579b84db0911e5

例子:

代码语言:javascript复制
 # 回退前;
 $ cat hyy04.txt
 123
 # 回退到 abc3e(首次提交hyy04.txt)的时候
 $ git reset --hard abc3
 HEAD is now at abc3e82 hyy04.txt首次提交到本地仓库
 
 # 回退之后查看
 $ cat hyy04.txt
 dapkiihwoia

现在又想恢复被撤销的提交可用 "git reflog"查看仓库中所有的分支的所有更新记录,

包括已经撤销的更新,撤销方法与前面一样。

代码语言:javascript复制
 $ git reflog
 abc3e82 (HEAD -> master) HEAD@{0}: reset: moving to abc3
 afd4392 HEAD@{1}: commit: 修改hyy04
 abc3e82 (HEAD -> master) HEAD@{2}: commit: hyy04.txt首次提交到本地仓库
 eaed0f7 HEAD@{3}: commit: 提交hyy03到本地仓库
 
 # 恢复被撤销的提交(即恢复到撤销前的时候:
 # afd4392【commit id】 HEAD@{1}【HEAD指针】: commit: 修改hyy04)
 $ git reset --hard HEAD@{1}
 HEAD is now at afd4392 修改hyy04
 # 或 git reset --hard afd4392
 # 恢复后查看
 $ cat hyy04.txt
 123

--hard:撤销并删除相应的更新 --soft:撤销相应的更新,把这些更新的内容放到 Stage 中

□ reset, restore, revert区别

在日常git工作流中,经常涉及到回退暂存区、回退工作区等撤销操作。 有三个名称相似的命令:git resetgit restoregit revert

  • git revert是进行新的提交,以还原其他提交所做的更改。 git revert <commit-id> 这条命令会把指定的提交的所有修改回滚,并同时生成一个新的提交。修改hyy04.txt 内容 echo "123"> hyy04.txt git add hyy04.txt git commit hyy04.txt -m"测试1" git reflog c464f23 (HEAD -> master) HEAD@{0}: commit: 测试1 afd4392 HEAD@{1}: reset: moving to HEAD@{1} abc3e82 HEAD@{2}: reset: moving to abc3 afd4392 HEAD@{3}: commit: 修改hyy04 abc3e82 HEAD@{4}: commit: hyy04.txt首次提交到本地仓库 # 回滚到 afd4392 HEAD@{3}: commit: 修改hyy04 的状态 git revert afd4392 # 然后就会进入到下面的页面(内容不是这次操作的) cat hyy04.txt dapkiihwoia
  • git restore使得在工作空间但是不在暂存区的文件撤销更改(内容恢复到没修改之前的状态) $ git add hyy05.txt $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: hyy05.txt # 可以看到此时的内容 $ cat hyy05.txt 1 # 修改内容但不add到暂存区 $ echo "12">hyy05.txt $ cat hyy05.txt 12 # restore:使得在工作空间但是不在暂存区的文件撤销更改 $ git restore hyy05.txt $ cat hyy05.txt 1
  • git restore --staged 是将暂存区的文件从暂存区撤出,但不会更改文件的内容。 $ git add hyy05.txt # 将暂存区的文件 hyy05.txt 从暂存区撤出 $ git restore --staged hyy05.txt $ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) hyy05.txt nothing added to commit but untracked files present (use "git add" to track)
  • git reset是关于更新分支,移动顶端(tip)以便从分支中添加或删除提交。 此操作更改提交历史记录。 git reset也可以用来还原索引,与git restore重叠。回退前; $ cat hyy04.txt 123 # 回退到 abc3e(首次提交hyy04.txt)的时候 $ git reset --hard abc3 HEAD is now at abc3e82 hyy04.txt首次提交到本地仓库 # 回退之后查看 $ cat hyy04.txt dapkiihwoia如下所示,我们通过git reset HEAD~1命令回退分支记录:
代码语言:txt复制
- Git 把 master 分支移回到 C1;现在我们的本地代码库根本就不知道有 C2 这个提交了。
- 在reset后, C2 所做的变更还在,但是处于未加入暂存区状态(可以通过`git reflog`查看日志文件查看记录,通过commit id|HEAD指针编号,`git reset --hard HEAD@{1}`回到指定状态)。
- `git reset hyy05.txt` 相当于`git add hyy05.txt`的逆操作,如果`hyy05.txt`时新建文件,则不起作用。 git add hyy05.txt   git reset hyy05.txt

16. 删除文件

□ 删除未跟踪文件

如果文件还是未跟踪状态,直接删除文件就可了,bash 中使用 rm 可以删除文件,示例如下:

代码语言:javascript复制
 $ git status
 On branch master
 Untracked files:
   (use "git add <file>..." to include in what will be committed)
         hyy05.txt
 
 nothing added to commit but untracked files present (use "git add" to track)
 
 $ rm hyy05.txt

□ 删除已提交文件

代码语言:javascript复制
 $ git ls-files # 查看已提交的文件
 hyy00.txt
 hyy02.txt
 hyy03.txt
 hyy04.txt
 
 $ git rm -f hyy00.txt
 rm 'hyy00.txt'

-f:强制删除,物理删除了,同时删除工作区和暂存区中的文件。

撤销删除:

git checkout -- <file>...

代码语言:javascript复制
 # 回到删除前的状态
 $ git reset HEAD@{0}
 Unstaged changes after reset:
 D       hyy00.txt
 
 $ git status
 On branch master
 Changes not staged for commit:
   (use "git add/rm <file>..." to update what will be committed)
   (use "git restore <file>..." to discard changes in working directory)
         deleted:    hyy00.txt
 
 # 现在是删除前的状态,
 $ git checkout -- hyy00.txt  
      
 $ git ls-files
 hyy00.txt
 hyy02.txt
 hyy03.txt
 hyy04.txt

□ 删除暂存区的文件,不删除工作区的文件

git rm --cached filename

代码语言:javascript复制
 $ git add hyy.txt
 $ git status
 On branch master
 Changes to be committed:
   (use "git restore --staged <file>..." to unstage)
         new file:   hyy.txt
         
 $ git rm --cached hyy.txt
 $ git status
 On branch master
 Untracked files:
   (use "git add <file>..." to include in what will be committed)
         hyy.txt
 
 nothing added to commit but untracked files present (use "git add" to track)

△ 文件操作小结

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

0 人点赞