• 基于Ubuntu18.04 学习
  • Git最初由linus编写
  • Git是编程必备的一个基础工具

创建版本库

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

#准备
$ mkdir learngit
$ cd learngit
$ pwd #显示当前路径
/home/qxd/learngit

#初始化
$ git init
Initialized empty Git repository in /home/qxd/learngit/.git/

#查看隐藏文件
$ ls -a
. .. .git

设置用户名和邮箱

  • 为什么要配置用户名和邮箱?

    因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址(名字和邮箱都不会进行验证),这样远程仓库才知道哪次提交是由谁完成的。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先Git相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。

$ git config --global user.email "710418455@qq.com"
$ git config --global user.name "qxd"

添加文件

  • 先在版本库文件夹下创建一个txt文件或者md文件
#第一步,用命令git add告诉Git,把文件添加到仓库:
$ git add readme.txt

#第二步,用命令git commit告诉Git,把文件提交到仓库:
$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
  • -m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
  • add和commit分开是为了分开添加不同的文件
  • 在commit前可以多次add

修改文件

#当修改了文件,可以查看当前的版本状态
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: readme.txt

no changes added to commit (use "git add" and/or "git commit -a")

#想查看版本库具体修改了哪些内容执行
$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
Git is free software.

#明确修改的内容再add
$ git add readme.txt

#此时查看版本库状态
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: readme.txt

#然后提交
$ git commit -m "add distributed"
[master f182c56] add distributed
1 file changed, 1 insertion(+), 1 deletion(-)

#查看当前版本库状态
$ git status
On branch master
nothing to commit, working tree clean

版本回退

#查看已提交的历史记录,顺序从上到下是最近到最远
$ git log
commit 0b0e509ff4af739ebacf8812e252fd2819a2a785 (HEAD -> master)
Author: qxd <710418455@qq.com>
Date: Sun Feb 13 04:07:05 2022 -0800

greatly

commit f182c5620f80f607a6c86ec94384b0c5ec4acaa6
Author: qxd <710418455@qq.com>
Date: Fri Feb 11 19:36:55 2022 -0800

add distributed

commit 3a535dd533058eb737bb8c0047147b9b0e546997
Author: qxd <710418455@qq.com>
Date: Fri Feb 11 18:55:42 2022 -0800

it is a test
#省去多余信息
$ git log --pretty=oneline
0b0e509ff4af739ebacf8812e252fd2819a2a785 (HEAD -> master) greatly
f182c5620f80f607a6c86ec94384b0c5ec4acaa6 add distributed
3a535dd533058eb737bb8c0047147b9b0e546997 it is a test

需要友情提示的是,你看到的一大串类似1094adb…的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。

$ git log --pretty=oneline
0b0e509ff4af739ebacf8812e252fd2819a2a785 (HEAD -> master) greatly
f182c5620f80f607a6c86ec94384b0c5ec4acaa6 add distributed
3a535dd533058eb737bb8c0047147b9b0e546997 it is a test

#当前版本回退到上一个版本
$ git reset --hard HEAD^
HEAD is now at f182c56 add distributed

#返回最新的版本,实际上根据commit的id号可以找到任意已记录的版本
$ git reset --hard 0b0e50
HEAD is now at 0b0e509 greatly

Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向另一个版本:

#用来记录你的每一次命令
$ git reflog
0b0e509 (HEAD -> master) HEAD@{0}: reset: moving to 0b0e50
f182c56 HEAD@{1}: reset: moving to HEAD^
0b0e509 (HEAD -> master) HEAD@{2}: commit: greatly
f182c56 HEAD@{3}: commit: add distributed
3a535dd HEAD@{4}: commit (initial): it is a test

工作区和暂存区

Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。

  • 工作区就是git init的文件夹
  • 暂存区实际上就是git add后,将修改的内容添加到.git的文件夹的待提交区域中

git-repo

  • 多次修改就要多次add,最后一起commit.没有add就只能提交stage区域的修改

  • 当没有及时提交时就会报错

    $ git status
    On branch master
    Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git checkout -- <file>..." to discard changes in working directory)

    modified: readme.txt

    no changes added to commit (use "git add" and/or "git commit -a")

    #把readme.txt文件在工作区的修改全部撤销
    git checkout -- readme.txt
    • 一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态
    • 一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

    git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。

  • 当需要退回暂存区的修改时

    $ git status
    On branch master
    Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)

    modified: readme.txt

    #可以把stage暂存区的修改撤销掉
    $ git reset HEAD readme.txt
    Unstaged changes after reset:
    M readme.txt

    git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。

删除文件

  • 当版本库和工作区一致时,删除某一个文件

    $ git status
    On branch master
    Changes not staged for commit:
    (use "git add/rm <file>..." to update what will be committed)
    (use "git checkout -- <file>..." to discard changes in working directory)

    deleted: test.txt

    no changes added to commit (use "git add" and/or "git commit -a")


    #如果确实要删除,
    $ git rm test.txt
    $ git commit -m "remove test.txt"

    #撤销删除
    $ git checkout -- test.txt

    git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

Git&Github的常用命令

#设置用户名和邮箱【每次进入都要设置】
git config --global user.name "yourname"
git config --global user.email "邮箱"
#生成密钥(SSH key)(生成的key通常在C:\Users\Husile\.ssh)
ssh-keygen -t rsa -C "your_email@youremail.com"
#检查密钥添加是否成功
ssh -T git@github.com
#创建本地仓库
cd d: 进入D盘
mkdir folder 创建一个folder文件夹
cd folder 进入folder文件夹
git init 将该文件夹设置为版本库
#连接到远程仓库 (两种有无https都可)
git remote add origin git@github.com:yourName/repositoryname.git
git remote add origin https://github.com/yourName/repositoryname.git
#如果要移除远程仓库
git remote rm origin
#从远程仓库pull文件
git pull origin master
#从本地仓库push文件
git push origin master
#将本地文件同步到远程仓库的步骤
git add . (记得加空格和点)
git commit -m "loading first time"
git remote add origin https://github.com/yourName/repositoryname.git
git push -u origin master
#另,在修改远程仓库时用得上
git config --global --unset http.proxy

#克隆一个本地库
$ git clone git@github.com:michaelliao/gitskills.git

如果有多个人协作开发,那么每个人各自从远程克隆一份就可以了。

你也许还注意到,GitHub给出的地址不止一个,还可以用https://github.com/michaelliao/gitskills.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。

使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https

Git本地更新


#使用如下命令可以查看远程仓库(我这里有一个origin仓库)
$ git remote -v
#使用如下命令可以在本地新建一个temp分支,并将远程origin仓库的master分支代码下载到本地temp分支
$ git fetch origin master:temp
#使用如下命令来比较本地代码与刚刚从远程下载下来的代码的区别:
$ git diff temp
#对比区别之后,如果觉得没有问题,可以使用如下命令进行代码合并:
$ git merge temp
#如果temp分支不想要保留,可以使用如下命令删除该分支:
$ git branch -d temp

Git分支管理

查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>或者git switch <name>

创建+切换分支:git checkout -b <name>或者git switch -c <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>

参考文献