安装git
linux系统安装
sudo yum install git
如果是基于Debian的发行版,即Ubuntu系统
sudo apt-get install git
mac系统安装
mac一般自带git
如果没有可到git官网进行下载:点击跳转官网下载安装包
直接下一步就可以。。。安装完成后,打开终端,输入git --version,即可显示版本。表示安装成功。
windows系统安装
到git官网进行下载:点击跳转官网下载安装包
直接下一步,可选择安装盘符。。。
安装完成后,点击右键会有Git Bash Here,点击后弹出命令行窗口,输入git --version,即可显示版本。表示安装成功。
git仓库的划分
-
Workspace:工作区,就是你在电脑里能看到的目录。
-
Index / Stage:暂存区,一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。通过add命令将工作区内容添加到暂存区。
.git是我们初始化目录时git自动创建的一个隐藏目录,里面存放的是我们所有的版本信息。勿动!!!
-
Repository:仓库区(或本地仓库),工作区有一个隐藏目录.git。通过commit命令将暂存区内容添加到仓库区。
-
Remote:远程仓库。通过push命令将暂存区的内容提交到远程仓库。
项目管理流程
先将项目代码fork到自己的账号下
在github或器他代码管理平台上右上方都有一个fork,表示将该用户的代码,fork到自己的账号下。
从远程仓库clone代码
最好使用clone从仓库中将项目代码克隆岛本地,如果是维护老项目,不使用clone直接进行下载的时候,在提交代码时会全部检测为新添加内容。导致无法进行code review
git clone 代码仓库的地址
初始化仓库
mac/linux系统打开终端切换到要管理的目录下,win系统可进入项目文件夹后,右键-->点击Git Bash Here,弹出终端。
# 在终端中输入下面命令,等于是让git开始管理这个目录下的所有内容了
git init
查看目录状态
git status # 查看当前目录下有哪些文件有变化,会以红色内容显示,此时文件在工作区
添加内容到本地的暂存区
git add 后面加需要管理的文件/目录
例:
git add . # 管理当前目录下的所有内容
git add test.py # 管理当前目录下的test.py文件
# 通过git add 管理的内容在查询状态时(git status)以绿色显示,即已经被管理到暂存区
个人信息配置
# 设置提交代码时的用户信息,即告诉git是谁提交的本次代码。
$ git config --global user.name "[name]"
$ git config --global user.email "[email address]"
使用global参数表示你这台机器上所有的Git仓库都会使用这个配置,global不是非必须参数。
检查已设置的配置信息,使用$ git config --list命令
生成版本,即add后到暂存区的文件提交到本地仓库
注意:如果是初次使用git管理未进行个人信息配置,直接执行此步骤会报错,需要先进行个人配置,如上一步。
git commit -m "此处填写该版本的描述信息"
# 提交暂存区的指定文件到仓库区,只是在上述命令中加入要提交的文件名
$ git commit [file1] [file2] ... -m [message]
# 使用一次新的commit,替代上一次提交,如果代码有变化需要进行add
# 如果代码没有任何新变化,则用来改写上一次commit的提交message信息
$ git commit --amend -m "message"
# 提交时显示所有diff信息,比较鸡肋,因为每次提交时可通过git status查看状态
$ git commit -v
查看版本记录
# 查看版本
git log
# 以流程的形式显示
git log --graph
# 查看所有的提交历史,只显示版本号和描述
git log --pretty=oneline
# 显示当前分支的最近几次提交
git reflog
版本回滚
已经进行commit后进行回滚
将(工作区)本地代码回滚到某个状态
git reset --hard 版本号 # 版本号可通过git log查看,想回滚到某个状态,版本号就是谁
回滚后如果还想再回到回滚之前的版本,还是通过上述代码进行,不过使用git log无法查到版本号,需要使用git reflog。
将本地仓库的代码回滚到暂存区,即回滚到add以后的状态
git reset --soft 版本号 # 将该版本号之前的版本回滚到暂存区
已经add后回滚
将add后(即暂存区版本)回滚到工作区
git reset HEAD # 执行完以后,再执行git status查看状态,会发现依然是红色,证明代码还在工作区。
从本地仓库直接回到工作区,即add之前状态
git reset --mix 版本号 # 该版本号的意思:将该版本号之前的版本回滚到工作区。
将本地修改撤销
git checkout . # 撤销工作区所有未进行add的文件内容修改,只针对于文件内容的修改,新增/删除文件无法撤销
git checkout 文件名 # 撤销对某一个文件内容的修改
分支
使用场景
-
多人协同开发,要创建自己的分支。
-
如果是已经上线的项目,需要开发新功能,但是此时项目出问bug了,那么就需要你进行紧急修复。如果没有分支,本地代码可能会受到影响,还需要涉及到代码冲突问题。
如果在开发新功能时,创建了单独的分支,那么在线上代码出问题时,可以直接切换到原来分支进行修改。
如果线上项目是一个分支dev1,自己正在开发的新功能是一个分支dev2,那么我们在切换回dev1分支时,本地代码会自动变成dev1时的状态,当dev1的bug修复完成后,可以再次切换到dev2分支,此时代码还是你正在开发时的状态。在dev1分支上修复的bug也不见了。
分支之间的代码互不影响
查看分支
查看所有本地分支
git branch
查看所有远程分支
git branch -r
列出所有本地分支和远程分支
git branch -a
创建分支
新建一个分支但是留在当前分支
git branch dev1 # 创建dev1分支
切换分支
切换分支,并更新工作区
git checkout dev1 # 切换到dev1分支,并更新工作区代码到当前分支
新建一个分支并切换到该分支
git checkout -b dev1 # 新建一个dev1分支,并切换到dev1分支上
删除分支
删除本地分支
git branch -d dev2 # 删除dev2分支
删除远程分支
git push origin --delete 远程分支名
合并分支
git merge bug # 合并bug分支到当前所在分支
合并分支时,会产生冲突,需要手动解决冲突后,提交。
重命名分支
本地分支重命名
git branch -m oldName newName
如果已经提交到远程仓库了,想要给远程仓库也修改名字。需要先删除远程仓库分支,然后直接git push
git branch -m dev1 develop-weida # 重命名dev1分支为develop-weida
git push origin --delete dev1 # 删除远程的dev1分支
git push origin develop-weida # 直接推送到远程仓库,会自动创建分支
线上项目bug修复
比如:master分支是我们线上跑的代码,此时我们开发新功能,需要建立一个新分支dev1,进行新的功能开发。此时项目出现bug,我们需要在master的基础上建立一个新的分支bug分支,然后在此分支上进行bug修复。此时相当于dev1分支和bug分支都是在master(线上代码分支)分支基础上进行的。修改完bug分支没有问题后,需要将bug分支代码合并到master分支上,然后将bug分支删除。此时再切换到dev1分支上继续开发,此时dev1分支上的bug还未修复。当dev1分支功能开发完毕后,要合并到master分支,此时会有冲突,需要手动解决冲突后,然后提交。
远程仓库
增加远程仓库
git remote add origin https://github.com/xxx/xxx.git(远程仓库地址)
# origin 就是我们起的别名
将本地仓库代码推送到远程仓库
git push origin master
origin 就是建立远程仓库连接时的别名
master 就是我们要提交到哪个分支
git push origin master -force # 将重置后的master分支强制推送更新
显示远程仓库信息
显示所有远程仓库
git remote -v
显示某个远程仓库信息
git remote show 远程仓库别名
取回远程仓库的变化,并与本地分支合并
git pull origin master
# 指定从某个远程仓库取回代码
git pull origin https://github.com/xxx/xxx.git dev1
git pull --rebase # 从服务器拉取最新代码
将git pull拆分
git pull origin dev1
上面代码,相当于
git fetch origin dev1 # 先将远程仓库代码拉到版本库
git merge orgin/dev1 # 将版本库中的代码合并到工作区
在远程仓库拉取代码过程可能出现的问题
- 在公司写了一个功能的代码,忘记提交。回到家后又写了另一个功能。第二天到公司后拉取代码可能或产生冲突。需要先手动解决冲突。
- 可能公司的代码让你先fork到你自己的github账号,然后让你对fork的代码进行修改,修改完成后通过pull request进行合并申请,与源代码合并。可能会出现,源代码一方将代码修改了,所以你需要与源代码同步。此时删除或者重命名你本地的那个分支,然后将远程仓库的分支删除。重新在本地建立分支,在本地git pull拉取源代码仓库的代码,直接git push 到你的仓库中,然后再将你之前可能添加新功能的代码进行合并。有冲突,先手动解决冲突。
rebase
将多个提交记录整合成一个
git push之前
commit 1cfce86cb8ceb0d9b8c5a6a7f0d49a5d554b6774 (HEAD -> dev1)
Author: xxx <123456@qq.com>
Date: Sun Dec 8 20:56:21 2019 +0800
版本3
commit ca334aaf85270b3283a7fc6e1b5c4d69cca7a5a7
Author: xxx <123456@qq.com>
Date: Sun Dec 8 20:36:25 2019 +0800
版本2
commit 9e4adfceb1be1a9c5d63a71dae03fbfa5ba1d392
Author: xxx <123456@qq.com>
Date: Sun Dec 8 19:13:13 2019 +0800
版本1
比如现在commit上面三条记录
# 第一种,按版本号
git rebase -i 9e4adf # 9e4adf版本号之后的版本到当前版本进行合并,不包含9e4adf
# 第二种,使用HEAD
git rebase -i HEAD~3 # 从当前开始最近的三条进行合并
执行完上述合并代码后,会出现如下代码,注释内容均是命令提示。
pick ca334aa 版本2
pick 1cfce86 版本3
# Rebase 9e4adfc..1cfce86 onto 9e4adfc (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
如果想要合并,我们需要将除第一个pick以外的pick改成s,意思是使用这个commit但是合并到上一个commit。结果如下:
pick ca334aa 版本2
s 1cfce86 版本3
然后切换到命令行模式,wq保存退出,然后会让你填写提交记录。
# This is a combination of 2 commits.
# This is the 1st commit message:
版本2
# This is the 1st commit message #2:
版本3
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sun Dec 8 20:36:25 2019 +0800
#
# interactive rebase in progress; onto 9e4adfc
# Last commands done (2 commands done):
# pick ca334aa 版本2
# squash 1cfce86 版本3
# No commands remaining.
# You are currently rebasing branch 'dev1' on '9e4adfc'.
#
# Changes to be committed:
# new file: xxx.py
#
修改如下:可以自定义写记录,我这里写成版本2 & 版本3,然后切换到命令行模式,wq保存退出即可。
# This is a combination of 2 commits.
# This is the 1st commit message:
版本2 & 版本3
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sun Dec 8 20:36:25 2019 +0800
#
# interactive rebase in progress; onto 9e4adfc
# Last commands done (2 commands done):
# pick ca334aa 版本2
# squash 1cfce86 版本3
# No commands remaining.
# You are currently rebasing branch 'dev1' on '9e4adfc'.
#
# Changes to be committed:
# new file: xxx.py
#
将分支记录插入到master,提交记录一条线
如果使用merge合并分支,那么在使用git log --graph时,会显示分支线路,使用rebase提交记录会显示在一条线上。
git checkout dev1
git rebase master # 将master分支上的代码与dev1合并
git checkout master
git merge dev1 # 再将dev1上的代码合并到master上
将远程代码下拉,提交记录一条线
如果公司忘记提交到远程仓库,在家写了新的功能提交到远程仓库,那么第二天回到公司git pull会出现提交记录分叉现象。使用rebase
git fetch origin dev1
git rebase origin/dev1
执行rebase命令遇到冲突情况
遇到冲突,先手动解决冲突,解决冲突后,会提示执行git add,然后再执行git rebase --continue
快速解决冲突
使用beyond compare软件
安装
https://www.scootersoftware.com/download.php
在git中配置
git config --local merge.tool bc3 # 给工具命名
git config --local mergetool.path '/usr/local/bin/bcomp' # 安装路径
git config --local mergetool.keepBackup false # 解决冲突后不保留备份文件
应用beyond compare解决冲突
git mergetool
打标签tag
标签分为轻量标签(lightweight)与附注标签(annotated),打上标签提交到远程仓库后,在该仓库中的releases中会有对应的版本,可以进行下载。
附注标签
创建附注标签
# 创建附注标签
git tag -a v4.0 -m "4.0版本"
v1.1是起的版本名
# 执行上述命令后,执行git log查看记录
$ git log
commit 86c90fd71fe1b48eb07eb3660a5c48485471eb04 (HEAD -> dev1, tag: v4.0)
Author: lwd <xxx@qq.com>
Date: Sun Dec 8 20:36:25 2019 +0800
版本4 & hello world功能
commit 9e4adfceb1be1a9c5d63a71dae03fbfa5ba1d392
Author: lwd <xxx@qq.com>
Date: Sun Dec 8 19:13:13 2019 +0800
版本2
查看有哪些标签
git tag
查看标签信息与对应的提交信息
# 查看提交信息
git show v4.0
# 显示结果如下,输出显示了打标签者的信息、打标签的日期时间、附注信息,然后显示具体的提交信息
tag v4.0
Tagger: lwd <xxx@qq.com>
Date: Mon Dec 9 21:48:41 2019 +0800
版本4.0
commit 86c90fd71fe1b48eb07eb3660a5c48485471eb04 (HEAD -> dev1, tag: v4.0)
Author: lwd <xxx@qq.com>
Date: Sun Dec 8 20:36:25 2019 +0800
版本4 & hello world功能
diff --git a/liuweida.py b/liuweida.py
new file mode 100644
index 0000000..95d09f2
--- /dev/null
+++ b/liuweida.py
@@ -0,0 +1 @@
+hello world
No newline at end of file
轻量标签
另一种给提交打标签的方式是使用轻量标签。 轻量标签本质上是将提交校验和存储到一个文件中——没有保存任何其他信息。 创建轻量标签,不需要使用 -a
、-s
或 -m
选项,只需要提供标签名字:
创建轻量标签
# 创建标签
git tag v4.1-lv
查看标签
git tag
查看标签信息与对应的提交信息
git show v4.1-lv
后期打标签
你也可以对过去的提交打标签。
git tag -a 标签名 版本号
git tag -a v4.2 9fceb02
远程仓库共享标签
共享标签
默认情况下,git push
命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样——你可以运行 git push origin [tagname]
。
git push origin v4.0
删除标签
删除本地仓库标签
git tag -d v4.1-lv
上述命令并不会从任何远程仓库中移除这个标签,你必须使用 git push <remote> :refs/tags/<tagname>
来更新你的远程仓库:
git push origin :refs/tags/v1.4-lw
git stash
git stash
会把所有未提交的修改(包括暂存的和非暂存的)都保存起来,用于后续恢复当前工作目录。
git stash pop
命令可以恢复之前缓存的工作目录。这个指令将缓存堆栈中的第一个stash删除,并将对应修改应用到当前的工作目录下。
git stash apply
命令,将缓存堆栈中的stash多次应用到工作目录中,但并不删除stash拷贝。可以通过名字指定使用哪个stash,默认使用最近的stash(即stash@{0})
git stash list
命令,查看现有的stash。
git stash drop
命令,移除stash。
git stash show
命令,后面可以跟着stash名字,可以查看指定stash的diff
git diff
# 比较工作区与暂存区
git diff 不加参数即默认比较工作区与暂存区
# 比较暂存区与最新本地版本库(本地库中最近一次commit的内容)
git diff --cached [filename]
# 比较工作区与最新本地版本库
git diff HEAD [filename] 如果HEAD指向的是master分支,那么HEAD还可以换成master
# 比较工作区与指定commit-id的差异
git diff commit-id [filename]
# 比较暂存区与指定commit-id的差异
git diff --cached [<commit-id>] [filename]
# 比较两个commit-id之间的差异
git diff [<commit-id>] [<commit-id>]
github简单介绍
公司项目一般会建立一个组织,将你拉入组织,然后为你创建一个分支,用于提交你的代码。
你进入组织的项目,将组织中项目的代码通过github中右上角有一个fork,fork到自己的仓库。
使用git clone 将代码下载克隆到本地,进行开发。
开发完成后,提交到你自己的仓库,通过pull request合并到组织中的仓库你的分支上。会有leader进行code review。
可能会出现的情况
如果组织仓库中的代码有更新,你的leader可能会让你先通过git pull拉取一下组织中的代码,可以先将你原来本地的分支重命名或者删除,然后拉取,拉取完毕后,删除你自己远程仓库的分支,直接进行git push。
git branch -m dev1 develop-weida
git branch dev1
git pull origin https://xxxxx/xxxx.git dev # 从组织仓库的dev分支拉取代码
git push origin --delete dev1
git push origin dev1
执行上述代码可能会有冲突,出现冲突就先手动解决冲突。如果原dev1中还有需要的代码,可以通过分支合并,将自己的新功能合并过来。
冲突
当你commit以后,在执行git pull --rebase的时候出现冲突,请按如下步骤解决:
1 找到冲突文件,解决冲突
2 执行git add xxx(xxx为冲突文件全路径)
3 执行git rebase --continue
4 执行git pull --rebase
5 执行git push
当你本地有修改的时候,你执行了git stash,然后又从服务器上pull了最新代码(git pull --rebase),出现了冲突,请按如下方式解决:
1 找到冲突文件,解决冲突
2 执行git add xxx(xxx为冲突文件全路径)
3 git commit
4 git pull --rebase
5 git push
git忽略文件
在git管理的目录下创建.gitignore文件。
在其中写入不需要管理的文件名、目录,当git管理该项目时,就不会将写入.gitignore文件中的内容管理起来。
.gitignore文件,比如,内容如下
a.py
*.h # 忽略所有.h结尾的文件
myfile/ # 忽略myfile目录下的所有内容
!b.h # 忽略管理时,排除b.h
github上有写好的大部分内容,可直接使用,如下:
python.gitignore文件:点击查看详细内容
// Byte-compiled / optimized / DLL files
pycache/
*.py[cod]
*$py.class
// C extensions
*.so
// Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
// PyInstaller
// Usually these files are written by a python script from a template
// before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
// Installer logs
pip-log.txt
pip-delete-this-directory.txt
// Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
// Translations
*.mo
*.pot
// Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
// Flask stuff:
instance/
.webassets-cache
// Scrapy stuff:
.scrapy
// Sphinx documentation
docs/_build/
// PyBuilder
target/
// Jupyter Notebook
.ipynb_checkpoints
// IPython
profile_default/
ipython_config.py
// pyenv
.python-version
// pipenv
// According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
// However, in case of collaboration, if having platform-specific dependencies or dependencies
// having no cross-platform support, pipenv may install dependencies that don't work, or not
// install all needed dependencies.
// Pipfile.lock
// PEP 582; used by e.g. github.com/David-OConnor/pyflow
pypackages/
// Celery stuff
celerybeat-schedule
celerybeat.pid
// SageMath parsed files
*.sage.py
// Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
// Spyder project settings
.spyderproject
.spyproject
// Rope project settings
.ropeproject
// mkdocs documentation
/site
// mypy
.mypy_cache/
.dmypy.json
dmypy.json
// Pyre type checker
.pyre/
</code>
点击此处,到github查看各种语言的gitignore文件