【Git】基本操作

【Git】基本操作

目录

创建 Git 本地仓库

配置 Git

认识工作区、暂存区、版本库

添加文件

场景一

查看 .git 文件

场景二

修改文件

版本回退

撤销修改

情况一:对于工作区的代码,还没有add

情况二:已经add ,但没有commit

情况三:已经add ,并且也commit 了

总结

删除文件


创建 Git 本地仓库

要提前说的是,仓库是进行版本控制的一个文件目录。我们要想对文件进行版本控制,就必须先创建一个仓库出来。
 

创建一个 Git 本地仓库对应的命令为 git init注意命令要在已经存在的文件目录下执行,之后这个文件目录就成了本地仓库,例如:创建gitcode目录,在gitcode目录下执行git init,gitcode就变成了本地仓库
hyb@139-159-150-152:~/gitcode$ pwd /home/hyb/gitcode hyb@139-159-150-152:~/gitcode$ git init Initialized empty Git repository in /home/hyb/gitcode/.git/ hyb@139-159-150-152:~/gitcode$ ll -a total 12 drwxrwxr-x 3 hyb hyb 4096 May 5 15:49 ./ drwxr-xr-x 13 hyb hyb 4096 May 5 15:47 ../ drwxrwxr-x 7 hyb hyb 4096 May 5 15:49 .git/

我们发现,当前目录下多了一个.git 的隐藏文件, .git 目录是 Git 来跟踪管理仓库的,不要手动
修改这个目录里面的文件,不然改乱了,就把 Git 仓库给破坏了。
其中包含 Git 仓库的诸多细节,有兴趣的可以进入看看。

hyb@139-159-150-152:~/gitcode$ tree .git/ .git/ ├── branches ├── config ├── description ├── HEAD ├── hooks │ ├── applypatch-msg.sample │ ├── commit-msg.sample │ ├── fsmonitor-watchman.sample │ ├── post-update.sample │ ├── pre-applypatch.sample │ ├── pre-commit.sample │ ├── pre-merge-commit.sample │ ├── prepare-commit-msg.sample │ ├── pre-push.sample │ ├── pre-rebase.sample │ ├── pre-receive.sample │ └── update.sample ├── info │ └── exclude ├── objects │ ├── info │ └── pack └── refs ├── heads └── tags 9 directories, 16 files

配置 Git

当安装 Git 后首先要做的事情是设置你的 用户名称 和 e-mail 地址,这是非常重要的。配置命令为:
git config [--global] user.name "Your Name" git config [--global] user.email "[email protected]" # 把 Your Name 改成你的昵称 # 把 [email protected] 改成邮箱的格式,只要格式正确即可。
其中 --global 是一个可选项。如果使用了该选项,表示这台机器上所有的 Git 仓库都会使用这个配置。如果你希望在不同仓库中使用不同的 name 或 e-mail ,可以不要 --global 选项,但要注意的是,执行命令时必须要在仓库里

查看配置命令为:

git config -l

删除对应的配置命令为:

git config [--global] --unset user.name git config [--global] --unset user.email

下图配置完后进行查看,可看到配置完成,其他的信息暂时可以不用管

下面是使用--global全局选项,需要注意的是使用全部选项配置会后,想要重新删除配置,也必须使用--global

认识工作区、暂存区、版本库

工作区是在电脑上你要写代码或文件的目录,即你本地仓库下除了.git之外的区域


暂存区英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,我们把暂存区有时也叫作索引(index)


版本库又名仓库,英文名 repository 。工作区有一个隐藏目录 .git ,它不算工作区,而
是 Git 的版本库
这个版本库里面的所有文件都可以被 Git 管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”

下面这个图展示了工作区、暂存区和版本库之间的关系:

图中左侧为工作区,右侧为版本库。Git 的版本库里存了很多东西,其中最重要的就是暂存区。


在创建 Git 版本库时,Git 会为我们自动创建一个唯一的 master 分支,以及指向 master 的一个指针叫 HEAD。(分支和HEAD的概念后面再说)



Git本身追踪管理的并不是文件,而是修改,对文件的每次修改除了文件本身,会形成一个新的object在objects区域内
工作区、暂存区、索引区内部都是通过树结构存储的。在工作区,每次我们在工作区进行修改(修改包括对文件的新增、删除、修改)后的结果都是作为对象进行保存的而版本库中有一块objects的区域专门存储这些对象,暂存区并不存储具体的对象,而是存储结果objects的索引当对工作区修改(或新增)的文件执行 git add 命令时,会将修改的结果推送给暂存区,,暂存区目录树的文件索引会被更新,存储指向objects区域内新对象的索引


•master内目录树存储的同样是指向objects的索引,当执行提交操作git commit 时,master 分支会做相应的更新,可以简单理解为暂存区的目录树才会被真正写到版本库中


由上述描述我们便能得知:通过新建或粘贴进目录的文件,并不能称之为向仓库中新增文件,而只是在工作区新增了文件。必须要通过使用 git add 和 git commit 命令才能将文件添加到仓库中进行版本管理

添加文件

场景一

在包含 .git 的目录下新建一个 ReadMe 文件,我们可以使用 git add 命令可以将文件添加到暂存区:


添加一个或多个文件到暂存区: git add [file1] [file2] ...


添加指定目录到暂存区,包括子目录: git add [dir]


添加当前目录下的所有文件改动到暂存区: git add .


再使用 git commit 命令将暂存区内容添加到本地仓库中:


提交暂存区全部内容到本地仓库中: git commit -m "message"


提交暂存区的指定文件到仓库区: git commit [file1] [file2] ... -m "message"


注意git commit 后面的-m 选项,就是用来进行添加备注的,对本次修改的说明,描述本次提交的 message,由用户自己完成,这部分内容绝对不能省略,并要好好描述,是用来记录你的提交细节,是给我们人看的,可以帮助我们更好理解每次操作的具体细节,有助于我们恢复到想要的版本,当迭代非常多次后想再恢复,这一点非常重要。

例如:

hyb@139-159-150-152:~/gitcode$ vim ReadMe hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello bit hyb@139-159-150-152:~/gitcode$ git add ReadMe hyb@139-159-150-152:~/gitcode$ git commit -m "commit my first file" [master (root-commit) c614289] commit my first file 1 file changed, 2 insertions(+) create mode 100644 ReadMe

git commit 命令执行成功后会告诉我们,1个文件被改动(就是我们新添加的ReadMe文件),插
入了两行内容(ReadMe有两行内容)。


我们还可以多次 add 不同的文件,而只 commit 一次便可以提交所有文件,是因为需要提交的文件是通通被 add 到暂存区中,然后一次性 commit 暂存区的所有修改。如:

hyb@139-159-150-152:~/gitcode$ touch file1 file2 file3 hyb@139-159-150-152:~/gitcode$ git add file1 hyb@139-159-150-152:~/gitcode$ git add file2 hyb@139-159-150-152:~/gitcode$ git add file3 hyb@139-159-150-152:~/gitcode$ git commit -m "add 3 files" [master 23807c5] add 3 files 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 file1 create mode 100644 file2 create mode 100644 file3

截至目前为止,我们已经能够将代码直接提交至本地仓库了。我们可以使用 git log 命令,来查看
下历史提交记录:

hyb@139-159-150-152:~/gitcode$ git log commit 23807c536969cd886c4fb624b997ca575756eed6 (HEAD -> master) Author: hyb91 <[email protected]> Date: Sat May 6 11:27:32 2023 +0800 add 3 files commit c61428926f3853d4ec6dde904415b0e6c1dabcc6 Author: hyb91 <[email protected]> Date: Sat May 6 11:25:50 2023 +0800 commit my first file

该命令显示从最近到最远的提交日志,并且可以看到我们 commit 时的日志消息。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline 参数,这个选项可以进行美化,将信息一行输出,接下来我们就能看到我们之前所做的操作都被记录来了,并且有一串字符串作为标识与之对应

hyb@139-159-150-152:~/gitcode$ git log --pretty=oneline 23807c536969cd886c4fb624b997ca575756eed6 (HEAD -> master) add 3 files c61428926f3853d4ec6dde904415b0e6c1dabcc6 commit my first file
需要说明的是,我们看到的一大串类似23807c5...56eed6 的是每次提交的 commit id (版本
号)
Git 的commit id 不是1,2,3……递增的数字,而是一个 SHA1 计算出来的一个非常大的数字,用十六进制表示(你看到的commit id 和我的肯定不一样,以你自己的为准)

查看 .git 文件

先来看看我们的.git 的目录结构:

hyb@139-159-150-152:~/gitcode$ tree .git/ .git/ ├── branches ├── COMMIT_EDITMSG ├── config ├── description ├── HEAD ├── hooks │ ├── applypatch-msg.sample │ ├── commit-msg.sample │ ├── fsmonitor-watchman.sample │ ├── post-update.sample │ ├── pre-applypatch.sample │ ├── pre-commit.sample │ ├── pre-merge-commit.sample │ ├── prepare-commit-msg.sample │ ├── pre-push.sample │ ├── pre-rebase.sample │ ├── pre-receive.sample │ └── update.sample ├── index ├── info │ └── exclude ├── logs │ ├── HEAD │ └── refs │ └── heads │ └── master ├── objects │ ├── 23 │ │ └── 807c536969cd886c4fb624b997ca575756eed6 │ ├── 83 │ │ └── 0a8c9feefbdc098bbae2cdc25e5034ce1920d7 │ ├── 8f │ │ └── add50161b6fafa53ce7e79d278dc490240c946 │ ├── 9c │ │ └── 9e1f0f6bff3015df71a0963004476f5e6cfd54 │ ├── c6 │ │ └── 1428926f3853d4ec6dde904415b0e6c1dabcc6 │ ├── e6 │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 │ ├── info │ └── pack └── refs ├── heads │ └── master └── tags 18 directories, 27 files
1. index 就是我们的暂存区,add 后的内容都是添加到这里的。


2. HEAD 就是我们的默认指向 master 分支的指针:
hyb@139-159-150-152:~/gitcode$ cat .git/HEAD ref: refs/heads/master

而默认的 master 分支,其实就是:

hyb@139-159-150-152:~/gitcode$ cat .git/refs/heads/master 23807c536969cd886c4fb624b997ca575756eed6

打印的23807c536969cd886c4fb624b997ca575756eed6 是什么东西呢?我们发现master存储的就是当前最新版本的commit id 。

objects 为 Git 的对象库,里面包含了修改过程中创建的各种版本库对象及内容当执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,就位于 ".git/objects" 目录下

让我们来看看这些对象有何用处:

hyb@139-159-150-152:~/gitcode$ ls .git/objects/ 23 83 8f 9c c6 e6 info pack
查找 object 时要将 commit id 分成2部分,其前2位是文件夹名称,后38位是文件名称
找到这个文件之后,一般不能直接看到里面是什么,该类文件是经过 sha (安全哈希算法)加密过的文件,好在我们可以使用 git cat-file 命令来查看版本库对象的内容
hyb@139-159-150-152:~/gitcode$ git cat-file -p 23807c536969cd886c4fb624b997ca575756eed6 tree 830a8c9feefbdc098bbae2cdc25e5034ce1920d7 parent c61428926f3853d4ec6dde904415b0e6c1dabcc6 author hyb91 <[email protected]> 1683343652 +0800 committer hyb91 <[email protected]> 1683343652 +0800 add 3 files # 我们发现这就是我们最近一次提交的相关描述信息 # parent发现存储的是上一次提交的commit id

其中,还有一行 tree 830a8c9feefbdc098bbae2cdc25e5034ce1920d7 ,我们使用同样的方
法,看看结果:

hyb@139-159-150-152:~/gitcode$ git cat-file -p 830a8c9feefbdc098bbae2cdc25e5034ce1920d7 100644 blob 9c9e1f0f6bff3015df71a0963004476f5e6cfd54 ReadMe 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file1 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file2 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file3

再看 ReadMe 对应的 9c9e1f0f6bff3015df71a0963004476f5e6cfd54 :

hyb@139-159-150-152:~/gitcode$ git cat-file -p 9c9e1f0f6bff3015df71a0963004476f5e6cfd54 hello bit hello bit # 这是我们对ReadMe做的修改!!被git记录了下来!!

所以我们发现我们对每一个文件所做的每一次操作所形成的版本都被git记录追踪了,并有唯一的commit id来标识

总结一下,在本地的 git 仓库中,有几个文件或者目录很特殊


index: 暂存区, git add 后会更新该内容


HEAD: 默认指向 master 分支的一个指针


refs/heads/master: 文件里保存当前 master 分支的最新commit id


objects: 包含了创建的各种版本库对象及内容,可以简单理解为存放了 git 维护的所有修改


后面再学习过程中,最好能将常见的git 操作与.git 目录当中的结构内容变化对应起来,这样有利于我们理解git 细节流程。

场景二

学习到这里,我们已经清楚了如何向仓库中添加文件,并且对于工作区、暂存区、版本库也有了一定的认识。那么我们再展示一种添加文件的场景,能加深对工作区、暂存区、版本库的理解,示例如下:

hyb@139-159-150-152:~/gitcode$ touch file4 #1. 新增file4文件 hyb@139-159-150-152:~/gitcode$ git add file4 #2. 将file4添加到暂存区 hyb@139-159-150-152:~/gitcode$ touch file5 #3. 新增file5文件 hyb@139-159-150-152:~/gitcode$ git commit -m"add file" #4. 提交修改 [master 3d406c0] add file 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 file4

提交后发现打印了 1 file changed, 0 insertions(+), 0 deletions(-) ,意思是只有一个文件改变了,这时我们提出了疑问,不是新增了两个文件吗?再来回忆下, git add 是将文件添加到暂存区, git commit 是将暂存区的内容添加到本地仓库中。由于我们并没有使用 git add file5 ,file5 就不在暂存区中维护,所以我们 commit 的时候其实只是把已经在暂存区的 file4 提交了,而遗漏了工作区的 file5。如何提交 file5 呢?很简单,再次add , commit 即可。

修改文件

Git 比其他版本控制系统设计得优秀,因为 Git 跟踪并管理的是修改,而非文件。
什么是修改?比如你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。
让我们将 ReadMe 文件进行一次修改:

hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world

此时,仓库中的 ReadMe 和我们工作区的 ReadMe 是不同的,如何查看当前仓库的状态呢? git
status 命令用于查看在你上次提交之后是否有对文件进行再次修改

hyb@139-159-150-152:~/gitcode$ git status On branch master 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: ReadMe no changes added to commit (use "git add" and/or "git commit -a")

上面的结果告诉我们,ReadMe 被修改过了,但还没有完成添加与提交。
目前,我们只知道文件被修改了,如果能知道具体哪些地方被修改了,就更好了。这里需要注意的是虽然这里我们所使用的例子简单,使用者直接指导哪里修改,但在实际开发中,我们面对的可能是几天、几个月前的修改,所以不能单纯靠人的记忆。

git diff [file] 命令用来显示暂存区和工作区文件的差异,显示的格式正是Unix通用的diff格
式。也可以使用 git diff HEAD -- [file] 命令来查看版本库和工作区文件的区别

知道了对 ReadMe 做了什么修改后,再把它提交到本地仓库就放心多了。

hyb@139-159-150-152:~/gitcode$ git diff ReadMe diff --git a/ReadMe b/ReadMe index 9c9e1f0..4a97140 100644 --- a/ReadMe #---、a都表示改动前,+++、bbb都表示改动后 +++ b/ReadMe @@ -1,2 +1,3 @@ #"-1"中的-表示改动前,1表示文件第一,后面的2表示从第1行开始有两行 hello bit #"+1"中的+表示改动后,1表示第一行,后面的3表示从第1行开始有三行 -hello bit #-表示删除的内容 +hello git #+表示新增的内容 +hello world
hyb@139-159-150-152:~/gitcode$ git add ReadMe hyb@139-159-150-152:~/gitcode$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: ReadMe

git add 之后,就没有看到上面 no changes added to commit (use "git add"
and/or "git commit -a") 的消息了。接下来让我们继续 git commit 即可:

hyb@139-159-150-152:~/gitcode$ git commit -m "add modify ReadMe file" [master 94da695] add modify ReadMe file 1 file changed, 2 insertions(+), 1 deletion(-) hyb@139-159-150-152:~/gitcode$ git status On branch master nothing to commit, working tree clean

版本回退

之前我们也提到过,Git 能够管理文件的历史版本,这也是版本控制器重要的能力。如果有一天你发现之前的工作做的出现了很大的问题,需要在某个特定的历史版本重新开始,这个时候,就需要版本回退的功能了。


执行 git reset 命令用于回退版本,可以指定退回某一次提交的版本。要解释一下“回退”本质是要将版本库中的内容进行回退,工作区或暂存区是否回退由命令参数决定:
git reset 命令语法格式为: git reset [--soft | --mixed | --hard] [HEAD]



• --soft 参数对于工作区和暂存区的内容都不变,只是将版本库回退到某个指定版本


• --mixed 为默认选项,使用时可以不用带该参数。该参数将暂存区的内容退回为指定提交版本内容,工作区文件保持不变


• --hard 参数将所有区域都退回到指定版本。切记工作区有未提交的代码时不要用这个命令,因为工作区会回滚,你没有提交的代码就再也找不回了,所以使用该参数前一定要慎重
git reset [--soft | --mixed | --hard] [HEAD]



• HEAD 说明:
◦ 可直接写成 commit id,表示指定退回的版本
◦ HEAD 表示当前版本
◦ HEAD^ 上一个版本
◦ HEAD^^ 上上一个版本
◦ 以此类推...
• 可以使用 ~数字表示:
◦ HEAD~0 表示当前版本
◦ HEAD~1 上一个版本
◦ HEAD^2 上上一个版本
◦ 以此类推...

为了便于表述,方便测试回退功能,我们先做一些准备工作:更新3个版本的 ReadMe,并分别进行3次提交,如下所示:

# 第一次修改提交 hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hyb@139-159-150-152:~/gitcode$ git add ReadMe hyb@139-159-150-152:~/gitcode$ git commit -m"add version1" [master cff9d1e] add version1 1 file changed, 1 insertion(+) # 第二次修改提交 hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hyb@139-159-150-152:~/gitcode$ git add ReadMe hyb@139-159-150-152:~/gitcode$ git commit -m"add version2" 1 file changed, 1 insertion(+) # 第三次修改提交 hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3 hyb@139-159-150-152:~/gitcode$ git add ReadMe hyb@139-159-150-152:~/gitcode$ git commit -m"add version3" [master d95c13f] add version3 1 file changed, 1 insertion(+) # 查看历史提交记录,前面的字符串就是每一步操作生成的版本的commit id # 我们也发现日志后边的记录就是我们commit时给的备注 hyb@139-159-150-152:~/gitcode$ git log --pretty=oneline d95c13ffc878a55a25a3d04e22abfc7d2e3e1383 (HEAD -> master) add version3 14c12c32464d6ead7159f5c24e786ce450c899dd add version2 cff9d1e019333318156f8c7d356a78c9e49a6e7b add version1 ...

现在,如果我们在提交完 version3 后, 发现 version 3 编写错误,想回退到 version2,重新基于
version 2 开始编写。由于我们在这里希望的是将工作区的内容也回退到 version 2 版本,所以需
要用到 --hard 参数,示例如下:

hyb@139-159-150-152:~/gitcode$ git log --pretty=oneline d95c13ffc878a55a25a3d04e22abfc7d2e3e1383 (HEAD -> master) add version3 14c12c32464d6ead7159f5c24e786ce450c899dd add version2 cff9d1e019333318156f8c7d356a78c9e49a6e7b add version1 ... #后面指定回退版本的commit id hyb@139-159-150-152:~/gitcode$ git reset --hard 14c12c32464d6ead7159f5c24e786ce450c899dd HEAD is now at 14c12c3 add version2 hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2

我们惊奇的发现,此时ReadMe 文件的内容,已经回退到 version2 了!,当前,我们再次用 git
log 查看一下提交日志,发现HEAD 指向了version2,如下所示:

hyb@139-159-150-152:~/gitcode$ git log --pretty=oneline 14c12c32464d6ead7159f5c24e786ce450c899dd (HEAD -> master) add version2 cff9d1e019333318156f8c7d356a78c9e49a6e7b add version1 ...

到这里一般回退功能就演示完了,但现在如果我后悔了,想再回到 version 3 怎么办?我们可以继续使用 git reset 命令,回退到 version 3 版本,但我们必须要拿到 version 3 的 commitid 去指定回退的版本。
但我们看到了 git log 并不能打印出 version 3 的commit id ,运气好的话我们可以从终端
上去找找之前的记录,运气不好的话 commit id 已经被我们搞丢了=。
因此Git 还提供了一个git reflog 命令能补救一下,该命令用来记录本地的每一次命令,比git log 记录更多。

hyb@139-159-150-152:~/gitcode$ git reflog 14c12c3 (HEAD -> master) HEAD@{0}: reset: moving to 14c12c32464d6ead7159f5c24e786ce450c899dd d95c13f HEAD@{1}: commit: add version3 14c12c3 (HEAD -> master) HEAD@{2}: commit: add version2 cff9d1e HEAD@{3}: commit: add version1 94da695 HEAD@{4}: commit: add modify ReadMe file 23807c5 HEAD@{5}: commit: add 3 files c614289 HEAD@{6}: commit (initial): commit my first file

这样,你就可以很方便的找到你的所有操作记录了,但d95c13f 这个是啥东西?这个是 version
3 的commit id 的部分。没错,Git 版本回退的时候,也可以使用部分commit id 来代表目标版
本。示例如下:

# 回退到v3 hyb@139-159-150-152:~/gitcode$ git reset --hard d95c13f HEAD is now at d95c13f add version3 # 查看工作区 hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3 # 查看log hyb@139-159-150-152:~/gitcode$ git log --pretty=oneline d95c13ffc878a55a25a3d04e22abfc7d2e3e1383 (HEAD -> master) add version3 14c12c32464d6ead7159f5c24e786ce450c899dd add version2 cff9d1e019333318156f8c7d356a78c9e49a6e7b add version1 94da6950d27e623c0368b22f1ffc4bff761b5b00 add modify ReadMe file 23807c536969cd886c4fb624b997ca575756eed6 add 3 files c61428926f3853d4ec6dde904415b0e6c1dabcc6 commit my first file

可往往是理想很丰满,现实很骨感。在实际开发中,由于长时间的开发了,导致 commit id 早就找
不到了,可突然某一天,我又想回退到 version3,那该如何操作呢?貌似现在不可能了。。。
值得说的是,Git 的版本回退速度非常快,因为 Git 在内部有个指向当前分支(此处是master)的
HEAD 指针, refs/heads/master 文件里保存当前 master 分支的最新commit id
当我们
在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储一个特定的version,可以简单理解
成如下示意图:

撤销修改

如果我们在我们的工作区写了很长时间代码,越写越写不下去,觉得自己写的实在是垃圾,想恢复到上一个版本。

情况一:对于工作区的代码,还没有add

你当然可以直接删掉你目前在工作区新增的代码,像这样:

# 向ReadMe中新增一行代码 hyb@139-159-150-152:~/gitcode$ git status On branch master nothing to commit, working tree clean hyb@139-159-150-152:~/gitcode$ vim ReadMe hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3 This piece of code is like shit #新增代码 hyb@139-159-150-152:~/gitcode$ git status On branch master 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: ReadMe no changes added to commit (use "git add" and/or "git commit -a") # 直接删除代码 hyb@139-159-150-152:~/gitcode$ vim ReadMe hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3 hyb@139-159-150-152:~/gitcode$ git status On branch master nothing to commit, working tree clean

辛亏我们工作效率不高,才写了一行代码就发现不行了,要是你写了3天,一直都没有提交,该怎么删掉呢?你自己都忘了自己新增过哪些,有人说,我可以git diff xxx 一下,看看差别在删啊,
那你肯定又要花3天时间删代码了,并且很大的概率还会改出bug。一周过去了,你怎么向你的老板交代呢?
Git 其实还为我们提供了更好的方式,我们可以使用 git checkout -- [file] 命令让工作区的
文件回到最近一次 add 或 commit 时的状态。 要注意git checkout -- [file] 命令中的
-- 很重要,切记不要省略,一旦省略,该命令就变为其他意思了
,后面我们再说。示例如下:

# 向ReadMe中新增一行代码 hyb@139-159-150-152:~/gitcode$ vim ReadMe hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3 This piece of code is like shit #新增代码 # 恢复到上一次 add 或 commit hyb@139-159-150-152:~/gitcode$ git checkout -- ReadMe hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3

情况二:已经add ,但没有commit

add 后还是保存到了暂存区呢?怎么撤销呢?

# 向ReadMe中新增一行代码 hyb@139-159-150-152:~/gitcode$ vim ReadMe hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3 This piece of code is like shit #新增代码 # add 存入暂存区 hyb@139-159-150-152:~/gitcode$ git add ReadMe hyb@139-159-150-152:~/gitcode$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: ReadMe

让我们来回忆一下学过的git reset 回退命令,该命令如果使用 --mixed 参数,可以将暂存区
的内容退回为指定的版本内容,但工作区文件保持不变。那我们就可以回退下暂存区的内容了!!!
示例如下:

# --mixed 是默认参数,使用时可以省略 hyb@139-159-150-152:~/gitcode$ git reset HEAD ReadMe Unstaged changes after reset: M ReadMe

用 git status 查看一下,发现现在暂存区是干净的,工作区有修改。

hyb@139-159-150-152:~/gitcode$ git status On branch master 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: ReadMe no changes added to commit (use "git add" and/or "git commit -a")

为了丢弃工作区的修改,我们使用上面的git checkout -- [filename]

hyb@139-159-150-152:~/gitcode$ git checkout -- ReadMe hyb@139-159-150-152:~/gitcode$ git status On branch master nothing to commit, working tree clean hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3

恢复了!

情况三:已经add ,并且也commit 了

不要担心,我们可以git reset --hard HEAD^ 回退到上一个版本!不过,这是有条件的,就是
你还没有把自己的本地仓库的版本通过git push推送到远程仓库(我们后面会讲到远程仓库,在实际开发中,我们的项目最终都是要上传到远端进行管理,我们之前所做的git回退一切努力就是为了不污染远程仓库),一但push到远程仓库,这种情况就无法回退了

# 向ReadMe中新增一行代码 hyb@139-159-150-152:~/gitcode$ vim ReadMe hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3 This piece of code is like shit #新增代码 # 提交 hyb@139-159-150-152:~/gitcode$ git add ReadMe hyb@139-159-150-152:~/gitcode$ git commit -m"test quash" [master 5f71ae1] test quash 1 file changed, 1 insertion(+) # 回退 hyb@139-159-150-152:~/gitcode$ git reset --hard HEAD^ HEAD is now at 144a3f8 add file hyb@139-159-150-152:~/gitcode$ cat ReadMe hello bit hello git hello world hello version1 hello version2 hello version3

总结

删除文件

在 Git 中,删除也是一个修改操作,我们实战一下, 如果要删除file5 文件,怎么搞呢?如果你这样
做了:

hyb@139-159-150-152:~/gitcode$ ls file1 file2 file3 file4 file5 ReadMe hyb@139-159-150-152:~/gitcode$ rm file5

但这样直接删除是没有用的,因为我们仅仅是在工作区做了修改, git status 命令会立刻告诉你哪些文件被删除了:

hyb@139-159-150-152:~/gitcode$ 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: file5 no changes added to commit (use "git add" and/or "git commit -a")

此时,工作区和版本库就不一致了,要删文件,目前除了要删工作区的文件,还要清除版本库的文
件。
一般走到这里,有两种可能:
• 确实要从版本库中删除该文件
• 不小心删错了
对第二种情况,很明显误删,需要使用 git 来进行恢复,很简单,删除也是修改,我们使用上面的回退操作就可以了:

hyb@139-159-150-152:~/gitcode$ git checkout -- file5 hyb@139-159-150-152:~/gitcode$ ls file1 file2 file3 file4 file5 ReadMe

对于第一种情况,很明显是没有删完,我们只删除了工作区的文件。第一种方式是先删除git中的文件,然后git add、git commit 将修改的版本推送到版本库

第二种方式是使用 git 提供的 git rm 将文件从暂存区和工作区中删除,然后再git commit :

hyb@139-159-150-152:~/gitcode$ git rm file5 rm 'file5' hyb@139-159-150-152:~/gitcode$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: file5 hyb@139-159-150-152:~/gitcode$ git commit -m"deleted file5" [master 5476bde] deleted file5 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 file5 hyb@139-159-150-152:~/gitcode$ git status On branch master nothing to commit, working tree clean

现在,文件就从版本库中被删除了。

Read more

【OpenClaw企业级智能体实战】第01篇:从零搭建你的第一个AI员工(原理+算法+完整代码+避坑指南)

【OpenClaw企业级智能体实战】第01篇:从零搭建你的第一个AI员工(原理+算法+完整代码+避坑指南)

摘要:随着AI从“对话时代”迈入“执行时代”,OpenClaw作为开源智能体框架,正在重塑人机协作模式——它不再是被动响应的工具,而是能主动执行任务的“AI员工”。本文基于真实技术原理与实操场景,从背景概念切入,拆解OpenClaw“感知-决策-执行”的核心逻辑,详解算法组件构建思路,并提供从零到一的完整实操流程(含可直接运行的Python代码)。内容兼顾新手入门与进阶提升,强调安全隔离部署原则,避开技术术语堆砌,聚焦实用价值。读者可通过本文掌握OpenClaw基础部署、自定义技能开发、记忆模块集成等核心能力,快速落地自动化办公、信息整理等实际场景,真正体验“低成本、高效率”的AI生产力革命。全文严格遵循真实性原则,无捏造案例与夸大描述,所有代码均经过实测验证。 优质专栏欢迎订阅! 【OpenClaw从入门到精通】【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】 【YOLOv11工业级实战】【机器视觉:C# + HALCON】【大模型微调实战:平民级微调技术全解】 【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】

By Ne0inhk

AI股票分析师daily_stock_analysis的Python入门教程

AI股票分析师daily_stock_analysis的Python入门教程 1. 前言:让AI帮你分析股票 你是不是经常盯着股票行情看花了眼?各种技术指标、新闻资讯、市场情绪,想要全面分析一只股票真的不容易。现在有个好消息:用Python和AI工具,你可以轻松搭建自己的智能股票分析系统。 今天我要介绍的daily_stock_analysis就是一个很棒的工具,它能够自动获取股票数据、分析技术指标、解读市场新闻,然后给你一份清晰的决策建议。最重要的是,这个工具完全免费,用Python就能快速上手。 无论你是编程新手还是有一定经验的开发者,跟着这篇教程,你都能在30分钟内搭建起自己的AI股票分析系统。我们会从最基础的环境配置开始,一步步实现完整的分析流程。 2. 环境准备与安装 2.1 系统要求 首先确认你的电脑环境: * Python 3.8 或更高版本 * 至少4GB内存(分析多只股票时建议8GB) * 稳定的网络连接(需要获取实时数据) 2.2 快速安装步骤 打开你的命令行工具(Windows用CMD或PowerShell,Mac/Linux用Ter

By Ne0inhk
黄仁勋力荐:OpenClaw不止是下一个ChatGPT,更是AI“动手时代”的破局者

黄仁勋力荐:OpenClaw不止是下一个ChatGPT,更是AI“动手时代”的破局者

在2026年GTC大会上,英伟达创始人兼CEO黄仁勋抛出了一个振聋发聩的判断:“OpenClaw绝对是下一个ChatGPT”。 这一评价并非夸大其词,而是精准点出了AI产业的核心演进方向——从“被动回答”的语言交互,转向“主动行动”的任务执行。ChatGPT开启了大语言模型(LLM)的普及时代,让AI具备了理解和生成人类语言的能力,但它始终停留在“军师”的角色,只能提供方案建议;而OpenClaw的出现,彻底打破了这一局限,将AI变成了能动手干活的“数字员工”,完成了AI从“认知”到“执行”的关键跃迁,成为连接AI能力与现实场景的核心桥梁。 下面我将从技术本质出发,拆解OpenClaw的核心架构、关键技术实现,结合代码示例、架构图与流程图,深入解析其如何实现“行动型AI”的突破,以及为何能被黄仁勋寄予厚望,成为AI产业的下一个里程碑。 一、认知跃迁:从“回答型AI”到“行动型AI”的本质区别 要理解OpenClaw的价值,首先需要明确它与ChatGPT这类“回答型AI”的核心差异。

By Ne0inhk

【人工智能】AI 智能体驾驭工程(Harness Engineering)全解析

AI 智能体驾驭工程(Harness Engineering)全解析 Harness Engineering(驾驭工程)是2026年初由OpenAI正式提出、并迅速成为AI Agent时代核心的软件工程新范式,其核心是将工程师的工作重心从直接编写代码/指令,转向设计、构建和迭代一套让AI智能体(Agent)能安全、可靠、高效完成复杂长周期任务的完整运行环境与制度体系,解决了Agent在大规模落地中出现的失控、漂移、错误级联、不可持续等核心痛点。 一、核心定义与提出背景 官方定义 OpenAI将Harness定义为让Agent能完成有用工作的系统工程,Harness Engineering则是持续设计、实现、迭代这套系统的方法论;Anthropic将其概括为「让模型真正成为可靠Agent的基础设施」;Martin Fowler/Thoughtworks则将其定义为「控制Agent各层循环的规格、质量检查与工作流指导体系」。 用最通俗的比喻: * 强大的AI模型是一匹爆发力极强的烈马; * Prompt Engineering是「对马喊话的技巧」,Context Engi

By Ne0inhk