• 用途: 做版本控制

    • 作用: 要保留之前所有的版本,以便回滚和修改
  • 操作方法

- 先自报家门,即'你是谁',两个命令:

git config --global user.email "agassics@sina.com"
git config --global user.name 'Anning'

- 进入要管理的目录,右键'git bash here'

- git init 初始化: 让git帮助我们管理当前文件夹

- git status: 检测当前目录下的文件状态

- git log: 查看当前版本

- 三种状态的变化:

    - 红色: 新增的文件/修改了原老文件 ==> git add 文件名

    - 绿色: git 已经管理起来 ==> git commit -m '描述信息'

    - 生成版本

git 三大区域

- 工作区

    - git init: 初始化git,并把目录里面的文件管理起来

    - 文件名会变红色

    - git add .: 把文件提交到'暂存区'

- 暂存区(缓存区,有后悔药吃)

    - 文件名会变绿色

    - git commit -m '功能描述': 把文件提交到'版本库'

- 版本库

    - 文件最终存放的地方
    

回滚

- 回滚至之前版本

    - git log

    - git reset --hard 版本号

- 回滚之后的版本

    - git reflog

    - git reset --hard 版本号

两个git命令测试

- git reset head(比较少用到,通俗讲,绿色退回红色): 把'暂存区'的文本,退回'工作区'

    - 即 git status 查看是,绿色的文件名

    - 运行 git reset head 后,再次运行 git status,变为'红色'

- git checkout -- filename(红色退回白色,即原始状态):

    - 把属于'工作区的红块'退回'工作区的白块'

    - 恢复文件至原来的状态


- 小结示例:

    - 往文件添加一行数据,然后 git add .(此时文件到达'暂存区(绿块)')

    - 绿块退回红块: git reset head

    - 红块退回白块: git checkout -- xxx.txt

git 输完命令不返回(出现end命令)

- 解决方式一: 按'q'

- 终极解决办法: git config --global core.pager ''

分支 Branch

  • 给开发者提供多个环境,把工作从开发主线上分离开来,以免影响开发主线
- git branch: 查看当前分支(有多少分支,就显示多少个)

- git branch branch_name: 新建分支

- git checkout dev: 切换到'dev分支'

    - git status: 可以看出,新建的'分支环境'是完全干净的

    - 修改文件,再git add,再git commmit,再git log,可以看出当前分支: HEAD -> dev

  • 把分支合并到'master'

- 新建 bug 分支,然后提交文件

    - git branch bug
    - 修改文件,git add . | git commmit -m 'xxx'

- 切换到'master',然后执行命令'git merge bug'

    - git checkout mater:

    - git merge bug

- 当bug分支被合并完成以后,我们就不需要bug分支了,可以把它删除,执行命令

    - git branch -d bug

    - 此时查看所有的分支: git branch,发现 bug 消失了

  • 小结
- git branch

- git branch branch_name

- git checkout branch_name

- git merge

    - 同一行代码可能产生冲突

    - 注意切换分支再合并

- git branch -d branch_name

- 最简单的'分支结构'

    - master 分支: 只放软件的'正式版本'(稳定版)

    - dev 分支: 各种测试版本


git 云端

- github(代码托管,fq)

- gitee(代码托管,无需fq,本示例)

- gitlab(适合公司内部搭建)
- 码云 注册账号

- 新建仓库

- 从0开始的命令集

    - mkdir tests
    - cd tests
    - git init
    - touch readme.md 
    - git add .
    - git commit -m 'first commit'
    # 若本地已存在仓库,则推送即可
    - git remote add origin https://gitee.com/anning_fun/tests.git
    # 此时推送的是'master分支',若想推送'dev分支',把'master'修改为'dev'即可
    - git push -u origin "master"(弹出认证,信息正确即可上传)

- 从远程仓库拉代码下来

    - git clone 远程仓库地址("所有分支"都会被下载下来): git clone https://gitee.com/anning_fun/tests.git

需求,在现有的'线上版本'基础上,开发新的功能

  • 肯定在dev分支上继续开发

    • 所以,要把master分支的代码合并过来,这样才是最新版本,保持和'线上版本'一致

    • 先切换到 dev 分支,执行合并命令: git merge master

  • 在 dev 分支上开发新功能,然后推送到远程仓库

    • touch new.py

    • git add . / git commit -m '开发了py功能'

    • git push origin dev

回到家继续开发,所以,先把远程仓库的代码拉下来

- 需要重新 git clone 吗? 不需要,只需把新增的功能代码拉下来即可

    - git clone 就是第一次,就是一无所有,才瞬间拥有一切

- 执行命令: git pull origin dev

- 继续开发新功能,然后推送到远程仓库

    - touch new2.py 

    - git add . / git commit -m '开发了new2.py功能'

    - git push origin dev

回到公司工作,先把代码拉下来

  • 执行命令: git pull origin dev,然后继续上述开发流程

小结

- 在公司进行开发

    - 切换到dev分支进行开发: git checkout dev

      - 新建分支并切换到该分支: git checkout -b dev

    - 要把master分支的代码合并过来[仅一次]: git merge master

    - 修改代码,提交代码

        - git add . / git commit -m 'xxx'

        - git push origin dev

- 回到家中继续写代码

    - 切换到dev分支进行开发: git checkout dev

    - 拉代码: git pull origin dev

    - 修改代码,提交代码

        - git add . / git commit -m 'xxx'

        - git push origin dev


- 在公司继续开发

    - 切换到dev分支进行开发: git checkout dev

    - 拉代码: git pull origin dev

    - 修改代码,提交代码

        - git add . / git commit -m 'xxx'

        - git push origin dev

- 开发完毕,要上线

    - 把dev分支合并到master,以便上线,最后推送到远程仓库

        - git checkout master

        -  gti merge dev

        - git push origin master

    - 把 dev分支也推送到远程仓库

        - git checkout dev

        -  git merge master

        - git push origin dev

rebase命令: 变基

  • 功能: 使 git log 记录更为简洁

  • 应用场景

比如老板交给你一段初始代码,然后开发功能
你可能会提交好几个版本,最后完成功能
这样,git log 都会记录这几个版本

对于老板来说,其实只需要最后开发完成的代码
中间的几次版本,根本不关心

针对这种场景, git rebase 可以简化git log的提交次数
  • 实例:先提交4个版本,然后合并最近的3个版本Log
- git log

commit a0b403634491fda82954584cbac813880537ae5c (HEAD -> master)
Author: anning <11388660+anning_fun@user.noreply.gitee.com>
Date:   Tue Aug 30 14:48:58 2022 +0800

    第四个版本记录

commit f88e792c4b458bdb9cc3d5e6bff3131c4db697a1
Author: anning <11388660+anning_fun@user.noreply.gitee.com>
Date:   Tue Aug 30 14:48:23 2022 +0800

    第三个版本记录

commit 975d803fa0ca75b8c5be6203bbaddedc3ce91a47
Author: anning <11388660+anning_fun@user.noreply.gitee.com>
Date:   Tue Aug 30 14:48:02 2022 +0800

    第二个版本记录

commit 183aadfe519af2867f116d8e52c578cc69460d86
Author: anning <11388660+anning_fun@user.noreply.gitee.com>
Date:   Tue Aug 30 14:47:42 2022 +0800

    第一个版本记录

  • 现在,合并最近的3次版本记录
- 执行命令: git rebase -i HEAD~3 # 合并最近的3次记录

pick d3dcf9c 第二个版本 # 保留
pick d05c72c 第三个版本 # 需要修改的地方
pick 7ab8d83 第四个版本 # 需要修改的地方

# Rebase 0472f98..7ab8d83 onto 0472f98 (3 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 [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# 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


pick d3dcf9c 第二个版本 # 保留
s d05c72c 第三个版本 # 把 pick 换成 s (注释)
s 7ab8d83 第四个版本 # 把 pick 换成 s (注释)
......

- 操作完毕以后,按"ESC键"然后按':wq',再按'回车键'(即保存以后,退出编辑),出现以下界面,可以继续编辑

# This is a combination of 3 commits.
# This is the 1st commit message:

第二个版本

# This is the commit message #2:

第三个版本

# This is the commit message #3:

第四个版本

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Tue Aug 30 15:45:13 2022 +0800
#
# interactive rebase in progress; onto 0472f98
# Last commands done (3 commands done):
#    squash d05c72c 第三个版本
#    squash 7ab8d83 第四个版本

- 操作完毕以后,按"ESC键"然后按':wq',再按'回车键',可以退回正常的git编辑界面

- 此时,执行 git log,显示版本信息,就是合并过后的'简洁版本'

commit d126e894167772c73fb4f0d8663e1a04eaa55006 (HEAD -> master)
Author: anning <11388660+anning_fun@user.noreply.gitee.com>
Date:   Tue Aug 30 15:45:13 2022 +0800

    第二个版本

    第三个版本

    第四个版本

commit 0472f98bc7b94edfff07d1a8948e65eb60e4a953
Author: anning <11388660+anning_fun@user.noreply.gitee.com>
Date:   Tue Aug 30 15:44:54 2022 +0800

    第一个版本

  • 注意事项

合并记录,不要合并已交到远程仓库的版本,会有大麻烦!

git rebase 的第二个作用: 把dev分支强插到master分支版本中间

  • 现在的git log 是这样: 只有两个版本
commit d126e894167772c73fb4f0d8663e1a04eaa55006 (HEAD -> master)
Author: anning <11388660+anning_fun@user.noreply.gitee.com>
Date:   Tue Aug 30 15:45:13 2022 +0800

    第二个版本

    第三个版本

    第四个版本

commit 0472f98bc7b94edfff07d1a8948e65eb60e4a953
Author: anning <11388660+anning_fun@user.noreply.gitee.com>
Date:   Tue Aug 30 15:44:54 2022 +0800

    第一个版本


- 以下所有命令要做的事情:把dev分支的代码合并到master分支

    - 现在,新建dev分支,然后新建文件,再提交

    - 切换到master分支,然后新建文件,再提交,然后把dev分支合并过来

    - 三个查看日志命令

        - git log

        - git log --graph

        - git log --graph --pretty=format:"%h %s"

  • 现在,使用 git rebase 做以下事情(把dev分支强插到master分支中间)
- 切换到 dev分支 ,把master分支合并过来,新建文件,然后提交

- 切换到master,新建文件,然后提交

- 切换到 dev分支,执行 git rebase master,然后切换到master,合并dev分支,再执行 git log --graph --pretty=format:"%h %s"

快速解决冲突: 安装 beyond compare

  • 在git中配置
git config --local merge.tool bc3 # 若是版本4,就是 bc4
git config --local mergetool.path '软件安装路径'
git config --local mergetool.keepBackup false
  • 应用 beyond compare 解决冲突
git mergetool

总结

  • 添加远程连接(别名)
git remote add origin 地址
  • 推送代码
git push origin dev
  • 下载代码
git clone 地址
  • 拉取代码
# 等价于: git fetch origin dev    git merge origin/dev
git pull origin dev

  • 保持代码提交整洁
git rebase 分支

vim 编辑

- vim 'file'

- 按'i'编辑,编辑完成以后

- 按esc,退出编辑,然后按":wq",回车保存并退出

版本编号控制:修改默认的哈希号,取'别名',就是所谓的'v1xx'版本

- git tag -a v1 -m '第一版'

- 再次 git log 查看

- 把版本号推送到远程仓库: git push origin --tags

    - 此时,远程仓库"标签"会显示 v1版本

给开源软件贡献代码(吹牛逼的资本)

  • fork 源代码: 将别人的源代码拷贝我自己的远程仓库

  • 在自己的仓库修改代码

  • 给源代码作者提交修复 bug 申请(pull request)

git 配置文件

  • 示例:需要修改配置,修改里面的内容即可
[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
[remote "origin"]
    url = https://gitee.com/anning_fun/tests.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[branch "dev"]
    remote = origin
    merge = refs/heads/dev
[merge]
    tool = bc4
[mergetool]
    path = D:\\BeyondCompare\\setup\\Beyond Compare 4
    keepBackup = false

git 配置

  • 项目配置文件: 项目/.git/config
git config --local user.name 'xxx'
git config --local user.email 'xxx@xx.com'

  • 全局配置文件(当前用户下): ~/.gitconfig(win系统是: .gitconfig)
git config --global user.name 'xxx'
git config --global user.email 'xxx@xx.com'

  • 系统配置文件: /etc/.gitconfig
git config --system user.name 'xxx'
git config --system user.email 'xxx@xx.com'

- 注意事项: Linux需要root权限

  • git 配置的查找顺序: 本项目配置->全局配置->系统配置

git 免密码登录

  • 在URL中体现
- 原来的地址: https://gitee.com/anning_fun/tests.git

- 修改配置文件中的地址: https://用户名:密码@gitee.com/anning_fun/tests.git

- 命令行:

    - git remote add origin https://用户名:密码@gitee.com/anning_fun/tests.git

    - git push origin master
  • SSH实现
- 生成公匙和私匙(默认放在 ~/.ssh目录下, id_rsa.pub公匙,id_rsa私匙)

    - ssh-keygen

- 拷贝公匙的内容,并设置到github中

- 在git本地中配置ssh地址

    - git remote add origin git@github.com:wupeiqi/dghot.git

- 以后使用

    - git push origin master
  • git自动管理凭证(首次推送到远程仓库的时候,输入凭据,剩下都无需再次输入)

git忽略文件

  • 比如保存密匙之类的文件,肯定不能上传到公共仓库

  • 新建并配置'.gitignore'文件,可以解决这个问题

- 新建'.gitignore'文件

- git status 

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

- 编辑'.gitignore'文件,比如输入'a.py',现在新建'a.py'这个文件,再次 git status

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

- 结论: 放入 '.gitignore'文件,是不会被git管理起来的,直接被忽略

- 注意事项: 配置'.gitignore'文件的文件名,支持各种'正则'的写法

- 拓展: python 常见的 '.gitignore'文件 配置

    - https://gitee.com/kd_cmad/Common_gitignore/blob/master/Python.gitignore

git实战

  • 码云上面新建仓库(新的规则,只能建私有,建完可以更改为公有)

  • 建完仓库以后,把代码拉到本地

git clone https://xxx.xxx/meiduo.git

- 进入仓库目录,输入 git status 查看状态

    - 新建dev分支并切换: git branch dev & git checkout dev

- 添加文件,然后提交,并推送到远程仓库(码云)
    
    - git add front_end

    - git comit -m "代码说明"

    - git push origin dev:dev # 推动到远程仓库的dev分支

    - 在码云 master 主分支上,发起合并,把dev分支的前端代码合过来(pull requests)