git基础


git工作流程

 使用git就是将本地文件(工作目录workspace)的文件,添加到暂存区(stage),然后提交到本地仓库(repository),最终可以协同开发,推送到远程仓库(remote)

git操作一、建立Git仓库

git版本库,也叫做git仓库(repository),也就是一个文件夹。

这个目录的所有内容被git软件管理,所有的修改,删除,git都会跟踪记录,便于可以跟踪历史记录,以后可以还原文件。

两种场景需求:

1.把已有的项目代码,纳入git管理

cd mysite    mysite项目所在代码
git init        初始化git仓库

git init命令会创建一个.git隐藏子目录,这个目录包含初始化git仓库所有的核心文件。
此步仅仅是初始化,此时项目里的代码还没有被git跟踪,因此还需要git add对项目文件跟踪,然后git commit提交到本地仓库

想知道.git文件做了什么事,请看git原理 >Git 内部原理 

2.新建一个项目,直接用git管理

cd 某个文件夹
git init mysite      此步会在当前路径创建mysite文件夹,mysite文件夹中包含了.git的初始化文件夹,所有配置

那么.git文件夹中有什么呢?

[root@pyyuc ~/git_learning/mysite 11:08:19]#tree .git
.git
├── branches
├── config    这个项目独有的配置
├── description
├── HEAD    head文件指示目前被检出的分支
├── hooks  hooks目录包含服务端和客户端的钩子脚本 hook scripts
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── index  index文件保存暂存区的信息,只有git add之后才会生成,默认还没有这个文件
├── info    info目录是全局性排除文件,用于放置不想被记录在.gitignore文件中的忽略模式(ignored patterns)
│   └── exclude
├── objects  存储所有数据内容
│   ├── info
│   └── pack
└── refs  refs目录存储指向数据(分支)的提交对象的指针
    ├── heads
    └── tags
.git文件夹解析

3.获取远程仓库代码

 如果你想获取github上的代码,或者你公司gitlab私有仓库的代码,可以使用git clone命令,下载克隆远程仓库的代码。

git clone https://github.com/django/django.git

你会发现所有的项目文件都在这里,等待后续开发。

git操作二、记录更新到本地仓库

还记得git的四个区域吗?本地文件夹,暂存区,本地仓库,远程仓库吗?

本地文件夹未初始化,git是不认识的

本地文件git init后,就成了git仓库

请记住,在工作文件夹的每一个文件,只有两种状态,一个是未跟踪,一个是已跟踪

已跟踪的指的是已经被纳入git版本管理的文件,在git快照中有他的记录

未跟踪的是这个文件既不在git快照中,也不在暂存区

git init初始化时的工作文件夹,都属于已跟踪了,后续的编辑操作都会标记为,已修改文件,因此需要将修改后的文件,加入暂存区,然后提交暂存区的文件

 检查文件状态

git status 
此命令查看git工作目录的文件,处于生命周期的哪一个状态 注意,只能在git工作目录中输入这个命令,他会去找.git文件夹 
第一次输入git status会看到此状态,没有任何东西需要提交
[root@pyyuc ~/git_learning/mysite 12:00:34]#git status
# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)

说明当前工作目录很干净,所有的已跟踪文件,已经被提交且未更改。
此时处在master默认分支。

git生命周期演练

请看代码

git init mysite                          初始化git仓库

git status                                 查看git状态

echo 'print("挣了一个亿")' > main.py        新建一个代码文件,此时是未被git跟踪的

git status                                查看状态

    On branch master

    No commits yet

    Untracked files:
      (use "git add ..." to include in what will be committed)

        main.py

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

git add main.py  开始跟踪main.py文件

git status   此时再看已经被跟踪,现在已是可以被提交的状态,此时处于暂存区

git commit -m "echo main.py" 告诉git,把暂存区的main.py提交到本地仓库

git log     查看刚才的commit记录

 给文件重命名

我们还是在git版本库中操作
修改main.py为mymain.py
mv main.py  mymain.py
查看状态
git status

直接mv的操作,会被git记录为两个形容,一、删除原有文件、二、新建了mymain.py文件
此时新文件还未被跟踪,需要git add , git commit
原本的main.py还需要从暂存区删除
[root@pyyuc
~/mysite 14:57:57]#git status # On branch master # Changes not staged for commit: # (use "git add/rm ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # deleted: main.py # # Untracked files: # (use "git add ..." to include in what will be committed) # # mymain.py no changes added to commit (use "git add" and/or "git commit -a")

git rm main.py  删除暂存区的main.py

git commit -m "mv mymain.py"  提交新的mymain.py

这样的步骤很麻烦,可以直接git mv 命令即可

刚才的mv记录,可以通过git log查看历史记录,已经提交的id

可以通过git reset 回退历史版本,回退到改名之前

[root@pyyuc ~/mysite 15:10:12]#git log
commit f60fa7f1312843aa57edc9464192c9d891f23fb5
Author: pyyu 163.com>
Date:   Sat Dec 22 15:08:02 2018 +0800

    mv mymain.py

commit 65e0a2239909fd5aabc5928ec4431de3f163a195
Author: pyyu 163.com>
Date:   Sat Dec 22 14:51:07 2018 +0800

    echo main.py


回退到上一次commit版本,(注意这个命令,很危险,慎用)
git reset --hard 65e0a2239909fd5aabc5928ec4431de3f163a195 
--hard 清空暂存区和工作目录资料

改名最正确的姿势

git mv main.py mymain.py  

git commit -m "mv mymain.py"

查看git版本历史

在我们使用git的时候,会对代码文件不停的修改,不断的提交到代码仓库。

这个就如同我们打游戏时候,保存关卡记录的操作。

在打boss之前,先做一个存档,防止你这个渣渣,被boss一招秒杀,又得从头再来。。。。。

因此被boss弄死,可以从存档,重新开始游戏。。。。

Git也是一样

当你的代码写好了一部分功能,就可以保存一个"存档",这个存档操作就是git commit,如果代码出错,可以随时回到"存档"记录

查看"存档"记录,查看commit提交记录的命令 git log

git log命令显示,从最新的commit记录到最远的记录顺序。

git log --oneline    一行显示git记录
git log --oneline  --all  一行显示所有分支git记录
git log --oneline --all -4 --graph 显示所有分支的版本演进的最近4条
git log -4  显示最近4条记录
git log --all     显示所有分支的commit信息




git branch -v 查看分支信息
git help --web log 以web界面显示log的参数

git版本回退,回到过去

git log可以查看历史版本记录
git reset --hard命令可以回退版本
git reset --hard HEAD^ 回退到上个版本
HEAD表示当前版版本
HEAD^表示上个版本
HEAD^^上上个版本

也可以直接git reset --hard 版本id号

 

git穿梭未来

当你发现你git reset --hard回退错了。。。怎么办?别怕git reflog 记录了你每一次命令

git reflog
80f9496 HEAD@{1}: reset: moving to HEAD^
b7a8740 (HEAD -> master) HEAD@{2}: commit: echo 123
80f9496 HEAD@{3}: commit: echo my.txt
bf5879e HEAD@{4}: commit (initial): echo my.txt

我想回到某一个点,可以再次git reset --hard 版本id

git工作区

在我们进行git init mygit初始化一个git项目时,这个mygit文件夹,就是一个工作区(working Directory)

yudanL-2:mygit root# pwd
/data/mygit
yudanL-2:mygit root# ls
.git    my.txt

git仓库

工作区里有一个.git隐藏文件夹,就是git的本地仓库

.git文件夹里有一个index文件,就是git的暂存区,也叫做stage

.git文件夹里的HEAD文件就是git的一个指针

原理图

git记录的是工作区的修改记录

撤销修改记录,只能在未提交到暂存区之前 

git status
git checkout -- my.txt 放弃工作区的修改操作

如果你修改了文件,还添加到了暂存区 git add,那么只能撤销暂存区的操作,再撤销修改记录

git status    
git reset HEAD readme.txt  撤销暂存区的修改,unstage操作
git checkout -- readme.txt

git删除文件与恢复文件

如果你直接在工作区删除文件,动作会被git记录
rm -rf my.txt    删除了工作区的文件,git仓库还有记录
git status    查看状态,可以检测到my.txt被删除

如果确认文件无用,可以commit到git仓库
git rm "my.txt"
git commit -m "remove my.txt"

如果你想恢复文件,可以通过git仓库的代码,替换工作区的代码

rm -rf my.txt
git checkout -- my.txt

git stash

保存当前暂存区和工作区的改动存储起来,执行完毕git stash之后,再次运行git status就会发现当前已是个干净的工作区,通过git stash list查看结果

命令整理

git stash 保存暂存区,工作区进度

git stash list 查看stash保存的列表以及id

git stash pop  恢复最新的stash进度到工作区

git stash pop stash_id  恢复指定的stash进度

git stash clear 清空所有存储的stash进度

git stash drop stash_id  删除一个存储的stash进度

git stash apply 恢复stash存储,且不删除stash list中的记录

git stash实际用法

git stash会把所有未提交的修改(包括暂存的和非暂存的)都保存起来,用于后续恢复当前工作目录。
比如下面的中间状态,通过git stash命令推送一个新的储藏,当前的工作目录就干净了。

[root@yugo mydjango]# ls
manage.py  mydjango
#比如我临时想新建一个app01,进行开发,但是突然开发到一半,线上代码出bug了,我得立即去修复,我希望能临时存储一下,我目前的修改操作,bug完毕了,再找回来继续开发
[root@yugo mydjango]# django-admin startapp app01
[root@yugo mydjango]#
[root@yugo mydjango]#
[root@yugo mydjango]# git add .
[root@yugo mydjango]# git status # On branch master # Changes to be committed: # (use
"git reset HEAD ..." to unstage) # # new file: app01/__init__.py # new file: app01/admin.py # new file: app01/apps.py # new file: app01/migrations/__init__.py # new file: app01/models.py # new file: app01/tests.py # new file: app01/views.py # [root@yugo mydjango]# [root@yugo mydjango]# [root@yugo mydjango]# git stash Saved working directory and index state WIP on master: b16ccc0 v1 mydjango HEAD is now at b16ccc0 v1 mydjango
#此时app01被放入暂存区,看不到了 [root@yugo mydjango]# ls manage.py mydjango

#这里应该使用 git stash save 存储名
git stash save "my app01 stash"

找回stash

[root@yugo mydjango]# ls
manage.py  mydjango
[root@yugo mydjango]# git stash pop # On branch master # Changes to be committed: # (use
"git reset HEAD ..." to unstage) # # new file: app01/__init__.py # new file: app01/admin.py # new file: app01/apps.py # new file: app01/migrations/__init__.py # new file: app01/models.py # new file: app01/tests.py # new file: app01/views.py # Dropped refs/stash@{0} (5758c689354a34a168063a5bfa5d4bb3ca291f3b)
[root@yugo mydjango]# ls app01 manage.py mydjango

查看stash列表

[root@yugo mydjango]# git stash list
stash@{0}: WIP on master: b16ccc0 v1 mydjango

移除stash

默认删除第一个stash
[root@yugo mydjango]# git stash drop
Dropped refs/stash@{0} (8af1c158977d5fe8bd398561ad8777514f8d22d1)
Git