Git
git的官方网站:http://git-scm.com
Git介绍
Git是一个开源的分布式版本控制软件,用以有效、高速的处理很小到大的项目版本管理。Git 最初是由Linus Torvalds设计开发的,用于管理Linux内核开发。Git 是根据GNU通用公共许可证版本2的条款分发的自由/免费软件,安装参见:http://git-scm.com/ Git就是一个用于帮助用户实现版本控制的软件。
GitHub是一个基于Git的远程文件托管平台。
Git本身完全可以做到版本控制,但其所有内容以及版本记录都只能保存在本机,如果想要将文件内容以及版本记录同时保存在远程,则需要集合github来使用。
首先将我们写好的项目建立好,并且下载好git后,使用git管理。
基础命令
1、初始化,让git把这个文件管理起来
git init
会出现.git文件,如果没有,将设置一下隐藏文件就可以了,正常情况下会是这种情况
Initialized empty Git repository in D:/python/gitdemo/.git/
2、查看当前文件夹的状态
git status
会显示:
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) .idea/ app01/ gitdemo/ manage.py templates/ nothing added to commit but untracked files present (use "git add" to track)
这个时候文件都还没有被管理,所以都是红色的
3、我们先随便对一个文件进行管理,例如:manage.py
git add manage.py(文件名) # 就是对当前文件版本控制
然后在查看一下状态:
git status
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: manage.py Untracked files: (use "git add <file>..." to include in what will be committed) .idea/ app01/ gitdemo/ templates/
此刻,manage.py是已经被管理的文件,颜色从红色变成了绿色。
4、对当前文件下的所有文件以及子目录进行版本控制
git add .
在查看,就是所有文件都被管理了:
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git add . warning: LF will be replaced by CRLF in .idea/gitdemo.iml. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in .idea/misc.xml. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in .idea/modules.xml. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in .idea/workspace.xml. The file will have its original line endings in your working directory. 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: .idea/gitdemo.iml new file: .idea/misc.xml new file: .idea/modules.xml new file: .idea/workspace.xml 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 new file: gitdemo/__init__.py new file: gitdemo/__pycache__/__init__.cpython-35.pyc new file: gitdemo/__pycache__/settings.cpython-35.pyc new file: gitdemo/settings.py new file: gitdemo/urls.py new file: gitdemo/wsgi.py new file: manage.py new file: templates/index.html
5、创建提交记录(版本)
git commit -m "详细描述版本信息"
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git commit -m '创建第一个版 本' [master (root-commit) 72d22fe] 创建第一个版本本 19 files changed, 504 insertions(+) create mode 100644 .idea/gitdemo.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/workspace.xml create mode 100644 app01/__init__.py create mode 100644 app01/admin.py create mode 100644 app01/apps.py create mode 100644 app01/migrations/__init__.py create mode 100644 app01/models.py create mode 100644 app01/tests.py create mode 100644 app01/views.py create mode 100644 gitdemo/__init__.py create mode 100644 gitdemo/__pycache__/__init__.cpython-35.pyc create mode 100644 gitdemo/__pycache__/settings.cpython-35.pyc create mode 100644 gitdemo/settings.py create mode 100644 gitdemo/urls.py create mode 100644 gitdemo/wsgi.py create mode 100644 manage.py create mode 100644 templates/index.html
如果在这一步报错了,就是没有写名字,和邮箱。按照所说的步骤来就行了。
这个时候我们再查看:
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master)
$ git status
On branch master
nothing to commit, working tree clean
已经为空,变成透明的了文件,实际上还是存在的。
6、查看信息,提交的记录
git reflog
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git reflog 72d22fe (HEAD -> master) HEAD@{0}: reset: moving to 72d22fe3836c39ae2a1e0e85e106 a41cc9b24898 c5cf29d HEAD@{1}: commit: 添加论文检查3功能 72d22fe (HEAD -> master) HEAD@{2}: commit (initial): 创建第一个版本本
7、回滚
git reset --hard (版本号)
8、暂存,用于在开发过程中临时需要修复bug或临时新功能的到来
stash用于将工作区发生变化的所有文件获取临时存储在“某个地方”,将工作区还原当前版本未操作前的状态;stash还可以将临时存储在“某个地方”的文件再次拿回到工作区。
git stash 作用:帮助我们暂时存储已经开发的一些功能的代码,继续做其他事情。做完之后再回来继续开发。
git stash pop
特别的:执行 git stash pop 命令时,可能会遇到冲突,因为在紧急修复bug的代码和通过stash存储在“某个地方”的代码会有重合部分,所以执行 git stash pop 时候就会出现冲突,有冲突解决冲突即可。
stash相关常用命令:
git stash 将当前工作区所有修改过的内容存储到“某个地方”,将工作区还原到当前版本未修改过的状态
git stash list 查看“某个地方”存储的所有记录
git stash clear 清空“某个地方”
git stash pop 将第一个记录从“某个地方”重新拿到工作区(可能有冲突)
git stash apply 编号, 将指定编号记录从“某个地方”重新拿到工作区(可能有冲突)
git stash drop 编号,删除指定编号的记录
9、与stash作用相同的是branch
分支学习:branch称为分支,默认仅有一个名为master的分支。一般开发新功能流程为:开发新功能时会在分支dev上进行,开发完毕后再合并到master分支。
git branch dev # 创建新分支,即:拷贝一份当前所在分支代码到新分支 git checkout dev # 切换到dev分支
分支功能完成后,再合并。合并之前要回到master,在合并
git checkout master # 切换回master分支 git merge dev # 将dev分支内容合并到master分支
代码:
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git branch dev # 创建分支 拷贝一份当前所在分支代码到新支 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git branch # 查看一下分支 dev * master 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git checkout dev # 切换到dev分支 Switched to branch 'dev' 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git add . # 将修改文件添加到版本库的暂存区 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git commit -m "论文修改3.1" # 将暂存区的内容提交到当前所在分支,即:dev分支 [dev beb0313] 论文修改3.1 1 file changed, 1 insertion(+) 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git status # 查看状态 On branch dev nothing to commit, working tree clean 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git checkout master # 切换到master Switched to branch 'master' 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git status On branch master nothing to commit, working tree clean 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git branch picc 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git checkout picc Switched to branch 'picc' 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (picc) $ git add . 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (picc) $ git commit -m "修改论文3.1.1" [picc 597a7e2] 修改论文3.1.1 1 file changed, 1 insertion(+), 1 deletion(-) 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (picc) $ git checkout master Switched to branch 'master' 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git merge picc # 合并 Updating c5cf29d..597a7e2 Fast-forward templates/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git log commit 597a7e216b13825f35a53932c7811fbbf7734187 (HEAD -> master, picc) Author: unknown <1079264692@qq.com> Date: Wed Mar 13 11:27:14 2019 +0800 修改论文3.1.1 commit c5cf29d6df4a152d82badeb414c89b2eb6711b28 Author: unknown <1079264692@qq.com> Date: Mon Mar 11 13:44:59 2019 +0800 添加论文检查3功能 commit 72d22fe3836c39ae2a1e0e85e106a41cc9b24898 Author: unknown <1079264692@qq.com> Date: Mon Mar 11 13:35:18 2019 +0800 创建第一个版本本 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git atatus git: 'atatus' is not a git command. See 'git --help'. The most similar command is status 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git status On branch master nothing to commit, working tree clean 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git branch -d picc # 删除这个分支 Deleted branch picc (was 597a7e2). 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git branch dev * master 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git checkout dev Switched to branch 'dev' 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git status On branch dev nothing to commit, working tree clean 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git status On branch dev nothing to commit, working tree clean 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git status On branch dev 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: templates/index.html no changes added to commit (use "git add" and/or "git commit -a") 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git add . 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git commit -m "论文暂时修改完" [dev 1ac93af] 论文暂时修改完 1 file changed, 1 insertion(+) 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git checkout master Switched to branch 'master' 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git merge dev Auto-merging templates/index.html CONFLICT (content): Merge conflict in templates/index.html Automatic merge failed; fix conflicts and then commit the result.
branch相关常用命令: git branch 分支名称 创建分支 git checkout 分支名称 切换分支 git branch -m 分支名称 创建并切换到指定分支 git branch 查看所有分支 git branch -d 分支名称 删除分支 git merge 分支名称 将指定分支合并到当前分支
面试题:
如果代码出现bug,如何解决?
创建一个bug分支,然后进行bug处理,处理完毕后合并到master分支,然后删除bug分支。最后回到dev分支继续开发。
最后,我们都写完功能后,如果是在家里边写完的,到公司以后如果没带电脑怎么办?这时候就有了GitHub托管平台。
GitHub介绍
GitHub,一个基于Git实现的代码托管的平台,可以将内容以及版本记录在远程也保存一份,这样就不用U盘咯(类似于云盘)。
PS: 类似GitHub的产品还有许多,如:GitLab、Bitbucket、码云等。
基于GitHub实现代码托管,需要一下步骤:
- 注册GitHub
- 创建仓库,创建完仓库后会有一个URL代指该仓库
- git可以是用该URL进行向远程推送版本信息或获取版本信息
在家里,将开发完的功能提交到GitHub
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git remote add origin https://github.com/lllmy/gitdemo.git # 为地址起一个别名origin 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git push origin master # 将本地master分支内容以及版本信息推送到GitHub
Enumerating objects: 42, done. Counting objects: 100% (42/42), done. Delta compression using up to 4 threads. Compressing objects: 100% (35/35), done. Writing objects: 100% (42/42), 9.41 KiB | 566.00 KiB/s, done. Total 42 (delta 10), reused 0 (delta 0) remote: Resolving deltas: 100% (10/10), done. To https://github.com/lllmy/gitdemo.git * [new branch] master -> master 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git branch dev * master 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (master) $ git checkout dev Switched to branch 'dev' 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git push origin dev # 将本地dev分支内容以及版本信息推送到GitHub Total 0 (delta 0), reused 0 (delta 0) remote: remote: Create a pull request for 'dev' on GitHub by visiting: remote: https://github.com/lllmy/gitdemo/pull/new/dev remote: To https://github.com/lllmy/gitdemo.git * [new branch] dev -> dev 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git pull origin dev remote: Enumerating objects: 7, done. remote: Counting objects: 100% (7/7), done. remote: Compressing objects: 100% (1/1), done. remote: Total 4 (delta 2), reused 4 (delta 2), pack-reused 0 Unpacking objects: 100% (4/4), done. From https://github.com/lllmy/gitdemo * branch dev -> FETCH_HEAD 1ac93af..54efe99 dev -> origin/dev Updating 1ac93af..54efe99 Fast-forward templates/index.html | 1 + 1 file changed, 1 insertion(+)
在公司,我们在GitHub上把在家里写的功能代码给拉下来
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa $ git clone https://github.com/lllmy/gitdemo.git # 将项目从GitHub中获取
Cloning into 'gitdemo'... remote: Enumera ting objects: 42, done. remote: Counting objects: 100% (42/42), done. remote: Compressing objects: 100% (25/25), done. remote: Total 42 (delta 10), reused 42 (delta 10), pack-reused 0 Unpacking objects: 100% (42/42), done. 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa $ ls gitdemo/ 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa $ cd gitdemo 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa/gitdemo (master) $ git branch # 默认获取到得只有master分支 * master 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa/gitdemo (master) $ git branch dev 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa/gitdemo (master) $ git checkout dev Switched to branch 'dev' 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa/gitdemo (dev) $ git pull origin dev From https://github.com/lllmy/gitdemo * branch dev -> FETCH_HEAD Already up to date. 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa/gitdemo (dev) $ git status On branch dev nothing to commit, working tree clean 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa/gitdemo (dev) $ git status On branch dev 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: templates/index.html no changes added to commit (use "git add" and/or "git commit -a") 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa/gitdemo (dev) $ git add . 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa/gitdemo (dev) $ git commit -m "会员功能1/3" [dev 54efe99] 会员功能1/3 1 file changed, 1 insertion(+) 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gggnaa/gitdemo (dev) $ git push origin dev Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 4 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (4/4), 368 bytes | 184.00 KiB/s, done. Total 4 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 2 local objects. To https://github.com/lllmy/gitdemo.git 1ac93af..54efe99 dev -> dev
123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ ls 2.py app01/ gitdemo/ manage.py* templates/ 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git fetch origin dev # 从GitHub仓库获取dev分支最新内容到版本库的分支 remote: Enumerating objects: 8, done. remote: Counting objects: 100% (8/8), done. remote: Compressing objects: 100% (3/3), done. remote: Total 6 (delta 3), reused 6 (delta 3), pack-reused 0 Unpacking objects: 100% (6/6), done. From https://github.com/lllmy/gitdemo * branch dev -> FETCH_HEAD d4cfd11..7f07a9e dev -> origin/dev 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ git merge origin/dev # 将版本库的分支内容合并到工作区 Updating d4cfd11..7f07a9e Fast-forward 1.py | 0 3.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 1.py create mode 100644 3.py 123456@LAPTOP-M4E1QDHK MINGW64 /d/python/gitdemo (dev) $ ls 1.py 2.py 3.py app01/ gitdemo/ manage.py* templates/
长此以往,将Git和GitHub结合使用做到避免电脑损坏造成数据丢失以及多地开发的问题,
上文执行过程中执行 【git pull origin 分支】命令等同于【git fetch origin 分支】+ 【git merge origin/分支】,
并且在执行过程中可能会出现冲突,原因是由于本地代码和获取的最新代码有重合部分,那么就需要自己手动解决冲突然后再继续开发。
面试题:
git rebase的作用?
我在公司写代码忘记提交了,在家继续开发功能,在拉取代码后提交,用git fetch和gitmerge提交的时候会有一个分叉记录,我们吧git merge换成git rebase会保持提交记录的整洁。
以斜杠“/”开头表示目录; 以星号“*”通配多个字符; 以问号“?”通配单个字符 以方括号“[]”包含单个字符的匹配列表; 以叹号“!”表示不忽略(跟踪)匹配到的文件或目录; .gitignore
在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改 .gitignore 文件的方法。这个文件每一行保存了一个匹配的规则例如: # 此为注释 – 将被 Git 忽略 *.a # 忽略所有 .a 结尾的文件 !lib.a # 但 lib.a 除外 /TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO build/ # 忽略 build/ 目录下的所有文件 doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt 这样设置了以后 所有的 .pyc 文件都不会添加到版本库中去。 另外 git 提供了一个全局的 .gitignore,你可以在你的用户目录下创建 ~/.gitignoreglobal 文件,以同样的规则来划定哪些文件是不需要版本控制的。 需要执行 git config --global core.excludesfile ~/.gitignoreglobal来使得它生效。 其他的一些过滤条件 * ?:代表任意的一个字符 * *:代表任意数目的字符 * {!ab}:必须不是此类型 * {ab,bb,cx}:代表ab,bb,cx中任一类型即可 * [abc]:代表a,b,c中任一字符即可 * [ ^abc]:代表必须不是a,b,c中任一字符 由于git不会加入空目录,所以下面做法会导致tmp不会存在 tmp/* //忽略tmp文件夹所有文件 改下方法,在tmp下也加一个.gitignore,内容为 * !.gitignore 还有一种情况,就是已经commit了,再加入gitignore是无效的,所以需要删除下缓存 git rm -r --cached ignore_file 注意: .gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。 正确的做法是在每个clone下来的仓库中手动设置不要检查特定文件的更改情况。 git update-index --assume-unchanged PATH 在PATH处输入要忽略的文件。 另外 git 还提供了另一种 exclude 的方式来做同样的事情,不同的是 .gitignore 这个文件本身会提交到版本库中去。用来保存的是公共的需要排除的文件。
而 .git/info/exclude 这里设置的则是你自己本地需要排除的文件。 他不会影响到其他人。也不会提交到版本库中去。 .gitignore 还有个有意思的小功能, 一个空的 .gitignore 文件 可以当作是一个 placeholder 。当你需要为项目创建一个空的 log 目录时, 这就变的很有用。
你可以创建一个 log 目录 在里面放置一个空的 .gitignore 文件。这样当你 clone 这个 repo 的时候 git 会自动的创建好一个空的 log 目录了。
git tag -a v1.0 -m '版本介绍' 本地创建Tag git show v1.0 查看 git tags -n 查看本地Tag git tag -l 'v1.4.2.*' 查看本地Tag,模糊匹配 git tag -d v1.0 删除Tag git push origin :refs/tags/v0.2 更新远程tag git checkout v.10 切换tag git fetch origin tag V1.2 git push origin --tags git pull origin --tags git clone -b v0.1 版本相关
先说一下相同点,二者都是基于web的Git仓库,在很大程度上GitLab是仿照GitHub来做的,
它们都提供了分享开源项目的平台,为开发团队提供了存储、分享、发布和合作开发项目的中心化云存储的场所。
GitHub作为开源代码库及版本控制系统,拥有超过900万的开发者用户,目前仍然是最火的开源项目托管系统。GitHub同时提供公共仓库和私有仓库,但如果要使用私有仓库,是需要付费的。
而GitLab解决了这个问题,你可以在上面创建私人的免费仓库。
GitLab让开发团队对他们的代码仓库拥有更多的控制,相比于GitHub,它有不少的特色:
允许免费设置仓库权限;允许用户选择分享一个project的部分代码;允许用户设置project的获取权限,进一步的提升安全性;
可以设置获取到团队整体的改进进度;通过innersourcing让不在权限范围内的人访问不到该资源。
从代码私有性方面来看,有时公司并不希望员工获取到全部的代码,这个时候GitLab无疑是更好的选择。但对于开源项目而言,GitHub依然是代码托管的首选。