Git 的笔记 | 青训营

60 阅读6分钟

为什么要学习Git

  • 协同工作
    业界绝大多数公司都是基于 Git 进行代码管理,因此 Git 是一个程序员的必备技能
  • 开源社区
    目前绝大多数的开源项目都是基于 Git 维护的,参与这些项目的开发都需要使用 Git

常见问题

  • 入职后按照文档进行 Git 配置,但是配置后依然拉取代码有问题,缺少自己排查配置问题的能力
  • 研发流程中进行一些异常操作,不符合研发规范,不清楚保护分支,MR / PR 等概念

代码托管平台

  • Github
    全球最大的代码托管平台,大部分的开源项目都放在这个平台上。
  • Gitlab
    全球最大的开源代码托管平台,项目的所有代码都是开源的,便于在自己的服务器上完成 Gitlab 的搭建
  • Gerrit
    由 Google 开发的一个代码托管平台,Android 这个开源项目就托管在 Gerrit 之上。

Git基本命令

image.png

项目初始化 mkdir study cd study git init 其他参数 --initial-branch 初始化的分支 --bare 创建一个裸仓库(纯 Git 目录,没有工作目录) --template 可以通过模版来创建预先构建好的自定义 git 目录

项目目录

image.png

git config

三个级别

--system $(prefix)/etc/gitconfig

--global ~/.gitconfig

--local .git/config 每个级别的配置可能重复,但是低级别的配置会覆盖高级别的配置:system>global>local

常见Git配置

用户名配置
git config --global user.name "liaoxingju"
git config --global user.email liaoxingju@bytedance.com
Instead of 配置
git config --global urlgit@github.com:.insteadOf https://github.com/
Git 命令别名配置
git config --global alias.cin "commit --amend --no-edit"

git remote

查看remote

git remote -v

配置源

git remote add origin_ssh git@github.com:git/git.git  
git remote add origin_http https://github.com/git/git.git

同一个 Origin 设置不同的 Push 和 Fetch URL 从一个开源仓库拉取代码,但推送到自己的仓库

git remote set-url --add --push origin git@github.com:MY_REPOSITY/git

git remote -v 查看

origin  git@github.com;git/git (fetch)
origin  git@github.com:MY_REPOSITY/git (push)

查看git/config也发生了变化

[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true
[remote "origin"]
        url = git@github.com:git/git.git
        fetch = +refs/heads/*:refs/remotes/origin/*
        pushurl = git@github.com:my_repo/git.git

区分http和ssh的remote,不同协议的身份认证

http

URL: github.com/git/git.git
免密配置
内存: git config --global credential.helper 'cache --timeout=3600'
硬盘: git config --global credential.helper "store --file /path/to/credential-file
不指定目录的情况默认是 ~/.git-credentials
将密钥信息存在指定文件中
具体格式: scheme://{scheme}://{use}:${password}@github.com

ssh(相对于http更加安全)

URL: git@github.com:git/git.git
免密配置
SSH 可以通过公私钥的机制,将生成公钥存放在服务端,从而实现免密访问
目前的 Key 的类型四种,分别是 dsa、rsa、 ecdsa、ed25519,默认使用的是 rsa, 由于一些安全问题,现在已经不推荐使用 dsa 和 rsa 了,优先推荐使用 ed25519

ssh-keygen -t ed25519 -C"your_email@example.com"   

密钥默认存在 ~/ssh/id ed25519.pub,将public的key存到github上

git add

git status git add .加入暂存区 git commit -m "add test"提交

.git/object对应的变化 git cat-file -p ega458grae4r8ag4rh8ag1ada15 image.png

标签一般是指一个稳定的版本,指向的Commit一般不会变更 git tag v0.0.1

追溯历史版本

修改历史版本

  1. commit --amend 通过这个命令可以修改最近的一次commit信息,commit_id并没有被删除

  2. rebase 通过 git rebase -i HEAD~3 可以实现对最近三个 commit 的修改: 1.合并 commit 2.修改具体的 commit message 3.删除某个 commit

  3. filter --branch 该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作

没有被删除的commit_id被悬空 git fsck --lost-found查询悬空的commit 删除多余的commit GC 通过 git gc 命令,可以删除一些不需要的 object, 以及会对 object 进行一些打包压缩来减少仓库的体积。 reflog 是用于记录操作日志,防止误操作后数据丢失 通过 reflog 来找到丢失的数据,手动将日志设置为过期 git reflog expire --expire=now --all 指定时间 git gc prune=now 指定的是修剪多久之前的对象 默认是两周前

git完整视图

image.png

远程和本地

Clone 拉取完整的仓库到本地目录,可以指定分支,深度 Fetch 将远端某些分支最新代码拉取到本地,不会执行 merge 操作 会修改 refs/remote 内的分支信息,如果需要和本地代码合并需要手动操作 Pull 拉取远端某分支,并和本地代码进行合并,操作等同于 git fetch + git merge, 也可以通过 git pull --rebase 完成 git fetch + git rebase 操作。 可能存在冲突,需要解决冲突 如果对远程不清楚推荐使用fetch然后本地rebase,如果比较清楚使用pull

冲突问题

  1. 如果本地的 commit 记录和远端的 commit 历史不一致,则会产生冲突,比如 git commit --amend or git rebase 都有可能导致这个问题。
  2. 如果该分支就自己一个人使用,或者团队内确认过可以修改历史则可以通过 git push origin master -f 来完成强制推送,一般不推荐主于分支进行该操作,正常都应该解决冲突后再进行推送。 推送规则限制 可以通过保护分支,来配置一些保护规则,防止误操作,或者一些不合规的操作出现,导致代码丢失。

常见问题

  1. 为什么我明明配置了 Git 配置,但是依然没有办法拉取代码?免密认证没有配。 Instead Of 配置没有配,配的 SSH 免密配置,但是使用的还是 HTTP 协议访问。

  2. 为什么我 Fetch 了远端分支,但是我看本地当前的分支历史还是没有变化? Fetch 会把代码拉取到本地的远端分支,但是并不会合并到当前分支,所以当前分支历史没有变化。

  3. 在 Gerrit 平台上使用 Merge 的方式合入代码:
    在 Gerrit 平台上,推荐使用 Code Review 的方式来合入代码,而不是直接使用 Merge。通过 Code Review,团队成员可以在代码合入之前进行评审和讨论,确保代码的质量和规范。直接使用 Merge 的方式可能会导致代码质量下降,因为没有经过团队的审查和讨论。

  4. 保护分支、Code Review 和 CI 的概念:

    • 保护分支是一种机制,用于限制对主分支的直接提交。它要求开发人员通过 Pull Request(PR)的方式来提交代码,以便进行评审和合入操作。
    • Code Review 是一种审查机制,通过由团队成员对代码进行审查和讨论,以确保代码质量和规范。这可以帮助发现潜在的问题、改进代码逻辑和提供更好的解决方案。
    • CI(持续集成)是一种自动化测试和构建的流程,它通过编写脚本和配置文件来验证代码的正确性、可靠性和性能。CI 可以帮助团队在代码合入之前进行自动化的测试和检查,以减少潜在的错误和问题。
  5. 代码历史混乱和代码合并方式不清晰:

    • Fast Forward 和 Three Way Merge 是两种常见的代码合并方式。Fast Forward 是一种简单的合并方式,它只会在没有冲突的情况下才进行合并,可以保持提交历史的简洁和清晰。Three Way Merge 是一种复杂的合并方式,它可以处理有冲突的情况,但会在提交历史中生成更多的合并节点。
    • 为了避免代码历史的混乱和不清晰,推荐使用 Fast Forward 的方式进行代码合并,只有在必要时才使用 Three Way Merge。此外,要定期进行代码整理和重构,以保持提交历史的简洁和可读性。