Pro Git02-Git基础

Pro Git02-Git基础

本文书接上文,继续写Git基础的一些场景的应用。

几种使用Git的场景

git简单工作流程

2.正常使用Git(没有线上的仓库)

  1. 在现有的目录种初始化仓库

如果你打算让git管理一个项目,而这个项目是没有git仓库的话,第一步就是初始化Git仓库:git init

1
2
3
4
5
6
7
8
9
10
11
12
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git status
fatal: not a git repository (or any of the parent directories): .git

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git init
Initialized empty Git repository in D:/BaiduSyncdisk/给公司电脑传输内容/git文章/new_git/.git/

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

第一次git status显示错误:这不是一个git仓库,而当我们初始化仓库以后,重新执行就不一样,这时候一个空的仓库就新建完成了,但是这仅仅是一个初始化的操作,你的项目里的文件还没有被跟踪,接下来就和上一个场景的使用方法一模一样了。下面的步骤的内容和上一个场景的对应标题的内容一模一样,就不重复赘述了。

  1. 检查当前文件状态
  2. 追踪新文件
  3. 暂存已修改的文件
  4. 提交更新
  5. 查看提交历史
  6. 推送到远程仓库(这一步开始不一样了)

接下来我快速过一遍之前的暂存提交

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
 D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git 的目录

2022/10/28 10:52 <DIR> .
2022/10/28 10:45 <DIR> ..
2022/10/28 10:52 24 readme.txt
1 个文件 24 字节
2 个目录 275,685,597,184 可用字节

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git status
On branch master

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)
readme.txt

nothing added to commit but untracked files present (use "git add" to track)

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git add readme.txt

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git commit -m '这是我的第一次提交'
[master (root-commit) a16d84e] '这是我的第一次提交'
1 file changed, 1 insertion(+)
create mode 100644 readme.txt

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git log
commit a16d84e7ddd34a5273d44b85289a1b45627b3608 (HEAD -> master)
Author: wuheng <849808229@qq.com>
Date: Fri Oct 28 10:53:25 2022 +0800

'这是我的第一次提交'

当我尝试使用git push来提交我的请求时,git会告诉你没有特定的线上仓库,需要设置。

1
2
3
4
5
6
7
8
9
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git push
fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

git remote add <name> <url>

and then push using the remote name

git push <name>
  1. 新建一个线上的远程仓库

接下来以码云为例,你需要先注册一个码云的账号(这个就不用演示了吧),新建一个空的线上仓库,当前其他地方。例如GitHub,也是大同小异罢了。

创建线上仓库流程01

创建线上仓库流程02创建线上仓库流程02

  1. 设置线上的远程仓库

实际上最后一张图,当你创建一个空的仓库时,码云已经告诉你要怎么执行了,不过我们还是细化重新讲一下。使用git remote add <shortname> <url>来添加一个新的远程仓库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git remote -v

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git remote add origin https://gitee.com/likebenboy/my_test.git

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git remote -v
origin https://gitee.com/likebenboy/my_test.git (fetch)
origin https://gitee.com/likebenboy/my_test.git (push)

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git remote add origin1 https://gitee.com/likebenboy1/my_test.git

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git remote -v
origin https://gitee.com/likebenboy/my_test.git (fetch)
origin https://gitee.com/likebenboy/my_test.git (push)
origin1 https://gitee.com/likebenboy1/my_test.git (fetch)
origin1 https://gitee.com/likebenboy1/my_test.git (push)

注意,远程仓库是可以添加多个的,而且远程仓库的名字不一样叫origin,它可以随便用其他名字,用这个的原因只是因为很多地方都约定俗成的东西而已,就像后面会提到的主分支叫master一样,实际上分支我让一个叫liekben的分支作为主分支也是可以的。不过还是按照约定的来,你的可读性会高一些。

  1. 真推送到线上仓库

我们设置好一切之后就可以直接提交了,你可能会注意到码云的命令让你输入:git push -u origin "master"。那当我们直接输入git push会怎么样呢?

1
2
3
4
5
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

git push --set-upstream origin master

git会问我们到底要提交到哪个远程仓库哪个分支,这里的origin和master就都是约定俗成的东西。origin代表主要的远程仓库,master代表主分支。而-u的参数是什么意思呢?

1
2
3
4
-u
set-upstream

For every branch that is up to date or successfully pushed, add upstream (tracking) reference, used by argument-less git-pull(1) and other commands. For more information, see branch.<name>.merge in git-config(1).

主要就是说branch..merge与branch..remote一起定义给定分支的上游分支(upstream)。它告诉git fetch/git pull要合并哪个分支,还可以影响git push.

而upstream是指其他人将从中获取的主要存储库,例如您的GitHub存储库。-u选项自动为您设置上游,将您的仓库链接到一个中央仓库。这样,将来Git会“知道”您要推送到的位置以及您要从哪里提取的信息,因此您可以使用git pull或git push不使用参数。 当您git pull从分支进行操作而未指定源远程或分支时,git会查看 branch..merge 设置以了解从何处提取。而正是git push -u 命令为您要推送的分支设置此信息。

至此,简单来说,带上-u 参数其实就相当于记录了push到远端分支的默认值,这样当下次我们还想要继续push的这个远端分支的时候推送命令就可以简写成git push即可。

这里引用我搜到的一篇文章:git push 的 -u 参数含义

我们直接按照git的提示来吧。注意这里的origin可以换成其他远程仓库名,master可以换成其他远程分支名字。都没有关系。

1
2
3
4
5
6
7
8
9
10
11
12
13
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git push --set-upstream origin master
remote: [session-914577bb] 849808229@qq.com: Incorrect username or password (access token)
fatal: Authentication failed for 'https://gitee.com/likebenboy/my_test.git/'

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git push --set-upstream origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 267 bytes | 89.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/likebenboy/my_test.git
* [new branch] master -> master
branch 'master' set up to track 'origin/master'.

这样以后就可以直接用git push,会自动推送到对应的master分支上。刚刚这里报错只是因为我密码输错了而已。

3.当我需要删除线上git仓库中的某个文件时

  1. 从远程仓库抓取与拉取(git pull)

我们这里假定你已经拥有了一个线上仓库和本地的仓库,别人刚上传了一个不需要在git上管理的文件,需要你来删除,那么现在的情况就是线上仓库与你本地的仓库内容不同,我们就需要先同步线上仓库的内容再继续进行修改。线上仓库与本地目录的对比1

线上仓库与本地目录的对比2

目前线上的仓库与本地的目录差了一个文件,也就是线上仓库的版本比本地多一个版本,我们需要从远程仓库拉取来让本地仓库与线上的版本保持一致。通常来说,使用git pull能够从线上仓库抓取数据然后尝试合并入分支(关于分支的知识点,将会在后续git分支的文章中重点介绍,这里的话你就默认只需要知道git pull会同步本地master分支与线上的master分支。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\copy_new_git\my_test>git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 390 bytes | 19.00 KiB/s, done.
From gitee.com:likebenboy/my_test
6248727..3dc664d master -> origin/master
Updating 6248727..3dc664d
Fast-forward
I am boy.txt | 0
need_delete.txt | 1 +
2 files changed, 1 insertion(+)
create mode 100644 I am boy.txt
  1. 移除文件

从Git中移除某个文件,需要把其从已跟踪的文件清单中移除,然后提交。不过这里有两个选择。

  1. 一种是我们想把文件从git仓库和本地的工作目录中都移除。那么只需要先删除文件,然后运行git rm xxx文件就行。类似以下操作:
1
2
3
4
5
6
7
8
9
10
11
12
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\copy_new_git\my_test>del "I am boy.txt"

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\copy_new_git\my_test>git rm "I am boy.txt"
rm 'I am boy.txt'

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\copy_new_git\my_test>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: I am boy.txt

然后正常提交就行,Linux的删除是rm,Windows删除文件的命令是del

  1. 另一种就是你希望这个文件还存在于你的工作目录中,但是不想这个文件被git跟踪了,那么你可以使用git rm --cached xxxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git rm --cached  "I am boy.txt"
rm 'I am boy.txt'

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: I am boy.txt

Untracked files:
(use "git add <file>..." to include in what will be committed)
I am boy.txt

然后正常提交就行,从输出也可以看出来,git提示I am boy.txt未被追踪。

其他一些小tips

  1. 移动文件

Git并不跟踪文件移动操作。如果我在工作目录修改了文件名,你会看到以下输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: I am boy.txt

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: readme.txt

Untracked files:
(use "git add <file>..." to include in what will be committed)
I am boy.txt
readme1.txt

Git会解读为新命名的文件没有被追踪,且以前的文件被删除了。我们使用git mv xxx newXXX可以让git知道被改名了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git mv readme.txt readme1.txt

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: I am boy.txt
renamed: readme.txt -> readme1.txt

Untracked files:
(use "git add <file>..." to include in what will be committed)
I am boy.txt

不过,其实运行git mv就相当于运行了下面三条命令:

1
2
3
$ mv readme.txt readme1.txt
$ git rm readme.txt
$ git add readme1.txt

以上的mv是Linux的重命名文件的命令,如此分开操作,Git也会意识到这是一次改名操作。

  1. 取消暂存文件

相信阅读时,你也看过很多次git status命令了,答案就藏在平时的输出中。

1
2
3
4
5
6
7
8
9
10
11
12
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: I am boy.txt
renamed: readme.txt -> readme1.txt

Untracked files:
(use "git add <file>..." to include in what will be committed)
I am boy.txt

git restore --staged就是撤销暂存的意思,以前git老版本可能会显示use "git reset HEAD <file>..." to unstage。新的restore命令专门用来恢复staged和worktree的文件。

1
2
3
4
5
6
7
8
9
10
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git restore --staged "I am boy.txt"

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: readme.txt -> readme1.txt

在调用git reset命令中加上--hard选项可能会让其成为一个危险的命令,不过本例中这种情况除外。不加选项地调用git reset并不危险,它只会修改暂存区域。

一般来说只能提交了的文件基本都能恢复,git中只有少数几个命令会让你本地的修改完全丢失,这就是我们口中的危险。

  1. 查看已暂存和未暂存的修改

如果你想查看具体这个文件两个提交记录之间到底修改了哪些地方,换句话说你想知道git status命令输出的条目中具体修改了文件的哪些内容,你就可以使用git diff命令。

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
D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: readme.txt -> readme1.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: readme1.txt


D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git diff
diff --git a/readme1.txt b/readme1.txt
index adbe101..8d3bf13 100644
--- a/readme1.txt
+++ b/readme1.txt
@@ -1 +1,2 @@
-这是该文件的内容
\ No newline at end of file
+这是该文件的内容
+这是我需要修改的内容
\ No newline at end of file

D:\BaiduSyncdisk\给公司电脑传输内容\git文章\new_git>git diff --cached
diff --git a/readme.txt b/readme1.txt
similarity index 100%
rename from readme.txt
rename to readme1.txt

添加参数--cached可以查看已暂存的将要添加到下次提交里的内容。

  1. 忽略文件

有时会有些文件无需纳入Git的管理,我们也不希望它总出现在未跟踪的列表中。比如一些日志文件,我们可以创建一个名为.gitignore的文件,列出要忽略的文件模式。

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
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/

### VS Code ###
.vscode/

文件 .gitignore 的格式规范如下:

  • 所有空行或者以 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配。(glob 模式是指 shell 所使用的简化了的正则表达式。)
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

上面的HELP.md代表git会忽略HELP.md这个文件。上面的*.iws代表会忽略所有以iws为后缀结尾的文件。target/代表会忽略target这个文件夹及其下面的所有文件。

  1. 远程仓库的移除和重命名

移除远程仓库为git remote rm paul,paul为远程仓库名。

重命名远程仓库为git remote rename pb paul,pb重命名为paul。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!