0%

Git收集

技术可以指人类对机器、硬件或人造器皿的运用,但它也可以包含更广的架构,如系统、组织方法学和技巧。它是知识进化的主体,由社会形塑或形塑社会。如电脑等新技术的增生使人们相信技术是社会进化的决定性力量,换句话说,它是驱动改变的自发性动力。

一、基础

  1. 介绍:Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。它是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。
  2. 安装git
    • Linux
      • 命令行安装
      • 源码编译安装
    • Mac OS
      • 通过homebrew安装
      • 通过xcode安装
    • Windows
      • 下载可安装文件直接安装
  3. 基本原理
    • git数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名
    • git是把数据看作是对小型文件系统的一组快照,每次你提交更新在git中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引
    • git用以计算校验和的机制叫做SHA-1散列(hash,哈希)。这是一个由40个十六进制字符(0-9和a-f)组成字符串,基于git中文件的内容或目录结构计算出来。
    • git有三种状态:已提交(committed)、已修改(modified)和已暂存(staged)。
      • 已提交表示数据已经安全的保存在本地数据库中
      • 已修改表示修改了文件,但还没保存到数据库中
      • 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中
    • git项目的三个工作区域的概念:git仓库、工作目录以及暂存区域
      • git仓库目录是git用来保存项目的元数据和对象数据库的地方。这是git中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据
      • 工作目录是对项目的某个版本独立提取出来的内容。这些从git仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改
      • 暂存区域是一个文件,保存了下次将提交的文件列表信息,一般在git仓库目录中,有时候也被称作’索引’
    • 基本的git工作流程如下:
      • 在工作目录中修改文件
      • 暂存文件,将文件的快照放入暂存区域
      • 提交更新,找到暂存区域的文件,将快照永久性存储到 git 仓库目录

        二、必杀技

  4. 所有的命令都可以查看手册,如:git init –help,以下只是常用的一些命令整理

三、常用操作

  1. git init
  2. git config –global user.name xxxx
  3. git config –global user.email xxxx@qq.com
    • –global 参数可选,带此参数则配置全局有效,不带则只有此仓库生效
  4. git add filename 添加文件到到暂存区
    • 开始跟踪新文件
    • 把已跟踪的文件放到暂存区
    • 合并时把有冲突的文件标记为已解决状态
  5. git commit 的使用
    • git commit -m ‘comment’ 推送暂存区修改并添加描述
    • git commit -a -m ‘comment’ 推送工作区修改并添加描述
    • git commit –amend -m 推送暂存区修改,覆盖上一次推送并添加描述
  6. git pull origin branch_name 拉取远程最新代码
  7. git push 的使用
    • git push branch_name 推送本地代码到远程
    • git push –delete branch_name 删除远程分支
      • 如:git push origin –delete v1.1.0
  8. git checkout 的使用
    • git checkout dev 切换分支(一是使 HEAD 指回 dev 分支,二是将工作目录恢复成 dev 分支所指向的快照内容)
    • git checkout -b [branchname] [tagname] 在特定的标签上创建一个新分支
    • git checkout – filename 撤销未添加到暂存区的修改
  9. git reset 的使用
    • git reset –hard commit_id 回滚指定提交的版本
    • git reset HEAD filename 撤销已添加到暂存区的修改
  10. git diff 的使用
    • git diff 当前做的哪些更新还没有暂存(只显示尚未暂存的改动)
    • git diff –cached 有哪些更新已经暂存起来准备好了下次提交
  11. git tag 的使用
    • git tag 列出已有标签
    • git tag tag_name 轻量标签
    • git tag -a tag_name -m ‘comment’ 打附注标签
    • git tab -a tag_name -m ‘comment’ commit_id 对某个提交打附注标签
  12. git show tag_name 查看标签相关信息

四、将本地代码托管到github

  1. 注册github账号、配置SSH-KEY、添加仓库repo等略过
  2. git remote 的使用
    • git remote -v 查看已经配置的远程仓库
    • git remote add 添加一个远程仓库并指定一个简写
  3. git fetch branch_name 从远程仓库中获得数据(不合并或修改当前的工作)
  4. git pull branch_name 从远程仓库中抓取数据并合并到当前所在的分支
  5. git push 的使用
    • git push tagname 推送指定标签到远程仓库
    • git push branch_name 推送分支到远程仓库
    • git push -u branch_name 第一次推送分支到远程仓库
  6. git remote show 查看远程仓库
  7. git remote rename old_name new_name 远程仓库的重命名
  8. git remote rm 远程仓库的重命名
  9. git config –global alias.别名 命令名 全局重命名命令
  10. git branch –set-upstream-to=origin/remote_branch local_branch 本地关联远程分支

五、git进阶

  1. 分支原理
    • git 保存的不是文件的变化或者差异,而是一系列不同时刻的文件快照, 会把代码仓库完整地镜像下来。
    • git 的分支,本质上仅仅是指向提交对象的可变指针。
    • 在 git 中,HEAD是一个指针,指向当前所在的本地分支。
    • 创建一个分支,只是创建了一个可以移动的新的指针。
    • git 的分支实质上仅是包含所指对象校验和(长度为40的SHA-1值字符串)的文件,所以它的创建和销毁都异常高效。
    • 创建一个新分支就相当于往一个文件中写入 41 个字节(40个字符和1个换行符)。

六、一台电脑配置两个github账户

  1. 背景交代:很早的时候用QQ邮箱注册了一个github账户,零零散散的写了一些东西,给人的感觉很不正式(找过工作的人都应该懂得),后来就用手机邮箱注又一个。那么问题来了,想同时在两个账号工作互不影响,手里就一台笔记本怎么办?如果你也有这样的问题那就看一下这篇文章吧。

  2. 准备工作:台式机OR笔记本一台,装好git,熟悉一些基本的git命令

  3. 撸起袖子开干

    • 生成两对秘钥放到C:\Users\Administrator.ssh目录下
      • 秘钥一
        • 输入命令ssh-keygen -t rsa -C “123456@qq.com
        • 在第一个提示后输入:id_rsa_one(如果默认第二次生成的会把第一次的覆盖掉)
        • 一路回车完事儿
      • 秘钥二
        • 输入命令ssh-keygen -t rsa -C “188****8888@163.com”
        • 在第一个提示后输入:id_rsa_two(分跟第一次生成的区分开)
        • 一路回车完事儿
    • 登录123456@qq.com的github账号,找到SSH and GPGkeys选项,点击New SSH key按钮,编辑打开id_rsa_one.pub,复制里面的内容粘贴到富文本框,随便起个名字然后保存
    • 登录188****8888@163.com的github账号,找到SSH and GPGkeys选项,点击New SSH key按钮,编辑打开id_rsa_two.pub,复制里面的内容粘贴到富文本框,随便起个名字然后保存
    • (可选)ssh-agent bash
    • (可选)ssh-add -l 如果为空就添加
    • 在C:\Users\Administrator.ssh目录下创建config文件,添加以下内容
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Host abc.com(名字随便起)                 
    HostName github.com(github账号必须得填github)
    IdentityFile C:\Users\Administrator\.ssh\id_rsa_one
    PreferredAuthentications publickey
    User abc

    Host xyz.com(名字随便起)
    HostName github.com(github账号必须得填github)
    IdentityFile C:\Users\Administrator\.ssh\id_rsa_two
    PreferredAuthentications publickey
    User xyz
    • 测试下配置成功了木,分别输入以下命令,如果成功了会有提示信息

      1
      2
      ssh -T git@abc.com 
      ssh -T git@xyz.com
    • 设置一个全局git账号

      1
      2
      git config --global user.name one
      git config --global user.email 123456@qq.com
    • 在github账号123456@qq.com下新建一个仓库test

    • 克隆到本地

      1
      2
      3
      4
      5
      原先的写法:
      git clone git@github.com:your_name/test.git

      现在的写法:
      git clone git@abc.com
    • 进入目录并设置git账号密码(非全局)

      1
      2
      git config user.name two
      git config user.email 188****8888@163.com
    • 正常编辑然后推送,登入github账号123456@qq.com,查看推送信息即可看到

  1. 问题:本地电脑配了好几个github、gitlab、gitee账号,同时也生成了好几对公私钥,当时配完了就不管了。后来突然有一天,本地码完代码之后推送到远程的时候不管用了(github上的私有仓库),一直提示Repository not found,BZ以为是本地仓库账号配错了,折腾了好久都不起作用。后来想到可能是哪个地方配错了,最终还真是这,再次记录下。
    • git push报错Repository not found
    • ssh -T git@github.com,账号明明对着了,就是提示git@github.com: Permission denied (publickey).
    • ssh -T git@liusir.me,即上面第七步,Hi liusirdotme! You've successfully authenticated, but GitHub does not provide shell access.
    • git remote add origin git@liusir.me:liusirdotme/liusirdotme.git
    • git push -u origin master

七、一次代码合并的错误

  1. 合并流程:开发分支develop合并到功能分支,功能分支合并到仿真分支,仿真分支合并到master
  2. 假设:
分支名称 最后一次正确提交ID 说明
master aaaaaaaa
fangzhe bbbbbbbb
develop cccccccc 罪魁祸首
v1.x.x dddddddd
  1. 处理步骤:
    • git reset –hard dddddddd && git push –force
    • git reset –hard bbbbbbbb && git push –force
    • git reset –hard aaaaaaaa && git push –force
    • 再分别把 v1.x.x 分别合到 fangzhen、master 上,其余正常操作就完事
  1. 感悟:
    • 生产环境数据处理首要考虑数据量,内存溢出,处理数据进度
    • git怎么提交、合并代码才能不出错
    • git代码合并错误回滚的步骤、常用操作命令

八、暂存

  1. 添加暂存git stash [--args]
    • 暂存未跟踪或忽略的文件 :-u/–include-untracked
    • 可以stash当前目录下的所有修改:-a/–all
  2. 重新应用暂存并删除原有暂存 git stash pop
  3. 重新应用暂存并保留原有暂存 git stash apply
  4. 查看暂存 git stash list
  5. 删除指定暂存 git stash drop stash@{0,1…n}
    • 删除所有暂存 git stash clear
  6. 基于暂存创建分支 git stash branch new_branch

九、常用操作

  1. 查看某个文件修改记录git log -- filenamegit log --pretty=oneline filename

  2. 查看某个作者修改记录git log --author=authorgit log --author=author --pretty=oneline

  3. 查看每次修改的文件列表及文件修改的统计git log --statgit whatchanged --stat

  4. 每次修改的文件列表并显示状态git log --name-status

  5. 每次修改的文件列表git log --name-only

  6. 查看某次提交git show commit_id

  7. 删除本地分支git branch -d branch_name

  8. 查看远程分支git branch -r

  9. 删除远程分支git push origin --delete branch_name

  10. 撤销add文件git reset HEAD filenamegit reset HEAD .

  11. 对比两个分支的差异

    • git diff branch1 branch2 –stat //显示出所有有差异的文件列表
    • git diff branch1 branch2 文件名(带路径) //显示指定文件的详细差异
    • git diff branch1 branch2 //显示出所有有差异的文件的详细差异
  12. git log中文文件名乱码,git config --global core.quotepath false

  13. git push时不用每次都输入用户名和密码:git config --global credential.helper store

  14. git config --unset user.name或全局git config --global --unset user.name

  15. Your account has been blocked,导致这个问题的原因有很多,接解决方案也就不同,我是第二种情况:

    • 方案一:重新设置远程仓库git remote set-url origin 远程仓库地址
    • 方案二:ssh模式下重新生成ssh-keygen -t rsa,并将id_rsa.pub生成的内容粘贴到gitlab后台
  16. 清除untracked files

    • 文件:git clean -nf
    • 目录:git clean -nfd
    • -n参数可用来查看删掉哪些文件
  17. 忽略已加入仓库的某个文件、文件夹

    • 修改本地仓库下的.gitignore文件,将要忽略的文件、文件夹加入
    • 执行命名git rm -r --cached file/dir
    • git push
  18. 使用脚本进行统计git log --author="liuyulong" --pretty=tformat: --since=2018-01-01 --until=2018-12-31 --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }'

  19. 忽略权限

    • git config core.filemode false git中加入忽略当前版本库文件权限的配置
    • git config --global core.fileMode false git中加入忽略所有版本库文件权限的配置
  20. 移除文件夹

1
2
3
git rm -r --cached folder
git commit -m 'remove folder'
git push
  1. 解决git push 中remote: Permission to xxxxx.git denied to xxx. fatal: unable to access ‘https://github.com/ xxxxx.git/‘: The requested URL returned error: 403。
1
2
3
4
5
6
7
8
9
10
11
12
13
#修改.git/cofig中的url
cd project
vim .git/config
将[remote "origin"]
url = https://github.com/git的用户名/仓库名称.git
修改为
url = https://git的用户名@github.com/git的用户名/仓库名称.git

#或者直接使用命令行:
git config remote.origin.url https://git的用户名@github.com/git的用户名/仓库名称.git

#重新推一下
git push -u origin master
  1. 查看信息

    • git log [<options>] [<revision range>] [[--] <path>...]
    • git show [<options>] [<object>...]
  2. push/pull好慢

    • 使用ipaddress.com
    • 查询最快的ip,我拿到的115.238.229.131
    • 修改/etc/hosts,添加115.238.229.131 github.global.ssl.fastly.net
    • 刷新本地DNS缓存sudo killall -HUP mDNSResponder
    • 使用tool.chinaz.com
    • 在浏览器打开http://tool.chinaz.com/dns
    • 输入github.com
    • 在输出列表中选择TTL值小的IP地址复制,如13.250.177.223
    • 粘贴到hosts文件13.250.177.223 github.com
    • 刷新下DNS缓存
  3. 删除本地分支并推送到远程

    • 方式一
    • git branch -d branch_name
    • git push origin :branch_name
    • 方式二
    • git branch -r -d origin/branch_name
    • git push origin :branch_name
    • git branch -D branch_name
    • 方式三
    • git push origin –delete branch_name
    • git branch -d branch_name

      扩展

    • git branch -a 查看本地和分支
    • git branch -r 查看远程分支
    • git branch -d branch_name 删除本地已merge的分支
    • git branch -D branch_name 删除本地分支(包含未merge)
  4. 将本地代码推送至github

    • git init
    • touch .gitignore,添加忽略文件
    • git add .
    • git commit -m ‘提交代码注释’
    • 去github创建仓库,假设仓库名叫study
    • git remote add origin https://github.com/你的github账户/study
    • git pull origin master –allow-unrelated-histories
    • git push -u origin master【需要输入github账号密码】
  5. 远程创建好分支并同步到本地

    • gitlab后台已创建好开发分支,如v5.5.5
    • 打开项目目录 code .
    • 创建并切换到本地分支 git checkout -b v5.5.5
    • git branch –set-upstream-to=origin/v5.5.5 v5.5.5
  6. Git只合并某几次提交

    • cd ~
    • git init git_cherry
    • cd git_cherry
    • vim master.txt
    1
    This is master file
    • git add .
    • git commit -m ‘master first commit’
    • git checkout -b develop
    • vim master.txt,增加以下内容
    1
    This edtion is in develop branch
    • git add .
    • git commit -m ‘in develop branch edit master.txt’
    • vim develop.txt
    1
    This is develop file
    • git add .
    • git commit -m ‘init develop.txt and commit’
    • git log,拿到需要合并的提交id
    • git checkout master
    • git cherry-pick commit_id
    • git log
  7. git修改remote origin

    • 直接修改git remote set-url origin url
    • 先删后加git remote rm origin && git remote add origin url
    • 直接修改config文件
    • 使用客户端修改如SourceTree

    博主本地有多个公私钥对:

    1
    2
    config           id_rsa.pub       id_rsa_dotme.pub
    id_rsa id_rsa_dotme known_hosts

    vim config

    1
    2
    3
    4
    5
    Host liusir.me
    HostName github.com
    IdentityFile /Users/your_name/.ssh/id_rsa_dotme
    PreferredAuthentications publickey
    User abc

    修改remote origin

    1
    2
    3
    4
    5
    git@github.com:liusirdotme/liusirdotme.git

    改为

    git@liusir.me:liusirdotme/liusirdotme.git
  8. command not found:gitk

    • 查看git版本 git --version //git version 2.20.1 (Apple Git-117)
    • 更新brew库 brew update
    • 重新安装git brew install git
    • 关闭重新打开 gitk,打完收工
  9. gitk模糊问题

    • 关闭rootless,重启mac,command+r,选择终端,输入csrutil disable
    • 查看rootless状态 csrutil status
    • 开启rootless csrutil enable –without debug
    • 修改Wish.app的Info.plist
    • 切换目录 cd /System/Library/Frameworks/Tk.framework/Versions/Current/Resources
    • 编辑Info.plist sudo gedit ./Wish.app/Contents/Info.plist
    • 加入以下代码 <key>NSHighResolutionCapable</key> <true/>
    • 更新Wish.app sudo touch Wish.app
    • 设置完毕后重新打开rootless csrutil enable
    • 参考
    • stackoverflow gitk command
    • mac下解决gitk模糊完整教程
  10. 本地新建分支并推到远程

    • 方式一
    1
    2
    3
    4
    5
    6
    7
    1.切换到master分支:git checkout master 
    2.拉取最新代码:git pull
    3.基于master创建featur_branch分支:git checkout -b feature_branch
    4.将本地分支关联到远程分支:git push origin feature_branch:feature_branch
    5.git branch --set-upstream-to=origin/remote_branch(名字自定义) feature_branch(刚建那分支名称)
    步骤4、5可换成以下命令:
    * git push --set-upstream origin feature_branch
  • 方式二

    1
    2
    git checkout -b v1.1.0_bugfix
    git push --set-upstream origin v1.1.0_bugfix
  1. remote: Password authentication is temporarily disabled as part of a brownout. Please use a personal access token instead.

    • git push报错
    1
    2
    3
    remote: Password authentication is temporarily disabled as part of a brownout. Please use a personal access token    instead.
    remote: Please see https://github.blog/2020-07-30-token-authentication-requirements-for-api-and-git-operations/ for more information.
    fatal: unable to access 'https://github.com/liusirdotme/liusirdotme.git/': The requested URL returned error: 403
    • 点击报错信息提供的url,可看到大概意思是加强了安全验证之类的

    • 根据指引,先去创建access_token,复制,等下要用

    • 创建完后根据指引去设置本地仓库

    • 验证是否安装osxkeychain helpergit credential-osxkeychain,正常会输出usage: git credential-osxkeychain <get|store|erase>

    • 设置git config --global credential.helper osxkeychain

    • 将本地的keychain删除

    • 打开Spotlight(command + space)

    • 输入keychain,实际打开的是keychain Access.app

    • 在列表中搜索github.com,移除

    • 重新git pull,要求输入用户名和密码,密码即刚刚生成的access_token

    • 参考

    • macOS Keychain

    • credentials

  2. 本地有修改,远程也修改了,且本地修改早于远程

  • git fetch –all
  • git reset –hard orgin/master
  • git pull
  1. 删除本地/远程分支

    • git branch -d feature/100
    • git push origin -d feature/100
  2. 忽略大小写:git config core.ignorecase true

十、修改commit message

  1. 修改已commit未push最近的提交

    • git commit –amend
    • 仅修改message:git commit --amend --message="new message"
    • 仅修改author:git commit --amend --author="new author@sm.com"
  2. 修改已commit已push最近的提交

    • git commit –amend
    • git push –force-with-lease
  3. 修改历史提交commit的信息

十一、CI

  1. gitlab的ci