Git

Git

初始化仓库

  • Git仓库实际上就是一个目录,需要对该目录进行Git的初始化将该目录交由Git管理
  • 初始化完成后,该仓库所有的文件都可以被Git进行管理,其所有修改删除等操作都会被跟踪到,也可以随时恢复到以前的版本

初始化本地仓库

  • 如果没有项目目录,可以创建一个新目录

  • 在项目目录中运行以下命令来初始化 Git 仓库:

    • git init
      
    • 这会在当前目录下创建一个隐藏的 .git 文件夹,用于存储 Git 的所有元数据和对象数据库。

      • 该隐藏的 .git 文件夹删除后该目录就变为一个普通的目录
    • 初始化后,当前目录就成为了一个 Git 仓库。

  • 如果已经有一个项目目录,可以直接在该目录中初始化 Git 仓库

配置邮箱和用户名

  • 在 Git 仓库初始化后,配置邮箱和用户名是必须的,但密码不是必须的

  • 邮箱和用户名用于标识提交的作者信息,而密码通常用于远程仓库的身份验证(如 GitHub、GitLab 等)。

  • Git 要求每次提交(commit)都记录作者信息,包括:

    • 用户名:标识提交的作者。
    • 邮箱:标识作者的邮箱地址。
    • 这些信息会包含在每次提交的元数据中,用于追踪代码的修改历史。
  • 全局配置(对所有仓库生效)

    • git config --global user.name "Your Name"
      git config --global user.email "your.email@example.com"
      
    • 不加--global的话就为局部配置(仅对当前仓库生效)

克隆远程仓库

  • 如果已经有一个远程仓库,可以直接克隆到本地:

    • git clone <远程仓库地址>
      
    • 这会在当前目录下创建一个与远程仓库同名的文件夹,并自动初始化 Git 仓库。

Git的工作区域

  • Git 的工作区域是 Git 版本控制系统的核心概念之一,理解这些区域对于高效使用 Git 至关重要。Git 的工作区域主要包括以下四个部分:
    • 工作区(Working Directory)
    • 暂存区(Staging Area)
    • 本地仓库(Local Repository)
    • 远程仓库(Remote Repository)

工作区(Working Directory)

  • 工作区是开发者直接编辑文件的目录。它是项目的根目录,包含所有正在开发的文件和文件夹。

  • 特点

    • 工作区中的文件可能是已跟踪的(tracked)或未跟踪的(untracked)。
      • 已跟踪的文件:已经被 Git 管理的文件(即已经添加到仓库或暂存区)。
      • 未跟踪的文件:新创建的文件或未被 Git 管理的文件。
    • 工作区中的文件可能处于以下状态之一:
      • 未修改(Unmodified):文件内容与本地仓库一致。
      • 已修改(Modified):文件内容被修改,但尚未添加到暂存区。
      • 已暂存(Staged):文件已被添加到暂存区,准备提交。
  • 命令

    • 查看工作区状态:

      • git status
        
    • 丢弃工作区的更改(恢复到上次提交的状态):

      • git checkout -- <文件名>
        

暂存区(Staging Area)

  • 暂存区是一个临时区域,用于保存即将提交到本地仓库的更改。开发者可以选择性地将工作区中的文件添加到暂存区。

  • 特点

    • 暂存区是 Git 的一个独特设计,允许开发者分阶段提交更改。
    • 只有添加到暂存区的文件才会被包含在下一次提交中。
  • 命令

    • 使用 git ls-files 命令可以列出暂存区的所有文件。

      • git ls-files
        
    • 将文件添加到暂存区:

      • git add <文件名>
        
        • 支持通配符比如git add *.txt表示将所有txt文件添加到暂存区
    • 添加所有更改的文件:

      • git add .
        
        • .代表当前目录
    • 从暂存区移除文件:

      • git reset HEAD <文件名>
        

本地仓库(Local Repository)

  • 本地仓库是存储项目完整历史记录的地方,包括所有提交、分支和标签。它位于项目目录下的 .git 文件夹中。

  • 特点

    • 本地仓库是分布式的,每个开发者都拥有完整的仓库副本。
    • 提交到本地仓库的更改不会自动同步到远程仓库。
  • 命令

    • 提交暂存区的更改到本地仓库:

      • git commit -m "提交信息"
        
    • **git commit -a **:自动暂存所有已跟踪文件的修改并提交

      • 自动暂存所有已跟踪文件的修改:包括修改、删除的文件,但不包括未跟踪的新文件。
      • 直接提交:将暂存的修改提交到仓库。
    • 查看提交历史:

      • git log
        
    • 撤销上一次提交(保留更改):

      • git reset --soft HEAD^
        
        • 撤销上一次提交,但保留更改(包括工作区和暂存区的更改)。

        • HEAD 指针移动到上一次提交(HEAD^),同时将撤销的提交的更改放回暂存区。

        • 其中HEAD^可以换成目标提交的 ID(使用 git log 查看)。

          • git reset --soft <commit-id>
            
    • 默认模式(保存工作区,丢弃暂存区)

      • git reset --mixed HEAD^
        等同于
        git reset  HEAD^
        
        • 重置暂存区,但保留工作区的更改(即撤销的提交的更改会放回工作区)。
    • 撤销上一次提交(丢弃更改):

      • git reset --hard HEAD^
        
        • 撤销上一次提交,并丢弃所有更改(包括工作区和暂存区的更改)。

        • HEAD 指针移动到上一次提交(HEAD^),同时重置工作区和暂存区到上一次提交的状态。

        • 如果执行了该命令还是可以回退版本的,因为git中的一切操作都是可以回退的

        • git reflog 记录了所有 HEAD 指针的移动历史,即使你已经重置了 HEAD,也可以通过它找回之前的提交。

          • 查看 reflog:其中包含<commit-id>

          • git reflog
            
          • 使用 git reset --hard 恢复到该提交:

          • git reset --hard <commit-id>
            

远程仓库(Remote Repository)

  • 远程仓库是存储在远程服务器(如 GitHub、GitLab、Bitbucket)上的仓库,用于团队协作和代码备份。

  • 特点

    • 远程仓库是集中式的,团队成员可以通过它共享代码。
    • 开发者需要将本地仓库的更改推送到远程仓库,或从远程仓库拉取最新更改。
  • 命令

    • 克隆远程仓库到本地:

      • git clone <远程仓库地址>
        
    • 查看远程仓库:

      • git remote -v
        
    • 推送本地仓库的更改到远程仓库:

      • git push origin <分支名>
        
    • 拉取远程仓库的更改到本地:

      • git pull origin <分支名>
        
  • 定义
    • HEAD 是一个非常重要的概念,它是指向当前工作目录所对应的提交(commit)的引用。
    • HEAD 是一个指针,指向当前所在的提交(commit)。
    • 它通常指向当前分支的最新提交,但也可以指向某个具体的提交(在分离头指针状态下)。
    • HEAD 是 Git 中用于跟踪当前工作状态的引用。
  • 作用
    • 指向当前分支,在大多数情况下,HEAD 指向当前分支的最新提交。例如:
      • 如果你在 main 分支上工作,HEAD 会指向 main 分支的最新提交。
      • 如果你切换到 feature 分支,HEAD 会指向 feature 分支的最新提交。
    • 分离头指针(Detached HEAD)
      • HEAD 直接指向某个具体的提交(而不是分支)时,称为分离头指针状态。
      • 这种状态通常出现在以下情况:
        • 直接检出某个提交(如 git checkout <commit-id>)。
        • 检出标签(如 git checkout v1.0)。
      • 在分离头指针状态下,新的提交不会属于任何分支,可能会导致提交丢失(如果没有创建分支)。
  • HEAD 的特殊符号
    • Git 提供了一些特殊符号来表示 HEAD 的相对位置:
      • HEAD^HEAD~1,表示 HEAD 的上一次提交(父提交)。
      • HEAD^^HEAD~2,表示 HEAD 的上两次提交。以此类推。

.gitignore文件

  • .gitignore 文件用于告诉 Git 哪些文件或目录应该被忽略,即不被 Git 跟踪或提交到仓库。

  • .gitignore 文件的作用

    • 忽略未跟踪的文件:防止 Git 跟踪某些文件或目录。
    • 避免提交不必要的文件:防止将临时文件、编译产物、敏感信息等提交到仓库。
  • 以下是一些常见的应该被忽略的文件类型:

    • 系统或编辑器生成的文件
    • 编译产物或构建输出
      • 编译生成的文件:如 *.class(Java)、*.o(C/C++)、*.pyc(Python)。
      • 构建输出目录:如 build/dist/out/
    • 依赖目录
      • 包管理器的依赖目录:如 node_modules/(Node.js)、vendor/(PHP Composer)、target/(Maven)。
    • 日志文件、测试输出和其他临时文件
  • .gitignore 文件的放置位置

    • 项目根目录:通常将 .gitignore 文件放在项目根目录下。
    • 子目录:可以在子目录中放置额外的 .gitignore 文件,规则仅对该目录生效。
  • .gitignore 文件的格式

    • 每行一个规则:每个规则指定一个文件或目录。
    • 支持通配符
      • *:匹配任意字符(除了 /)。
      • **:匹配任意目录。
      • ?:匹配单个字符。
      • []:匹配括号内的任意字符。
    • / 开头:匹配项目根目录下的文件或目录。
      • 根目录为.git文件所在目录
    • / 结尾:匹配目录。
    • ! 开头:排除某个文件或目录(即使被其他规则忽略)。
  • .gitignore 文件示例

    • # 忽略所有 .log 文件
      *.log
      
      # 忽略 build/ 目录下的所有文件
      build/
      
      # 忽略根目录下的 .env 文件
      /.env
      
      # 忽略所有 .tmp 文件,但不忽略 important.tmp
      *.tmp
      !important.tmp
      
      # 忽略 doc/ 目录下的 .txt 文件,但不忽略 doc/notes.txt
      doc/*.txt
      !doc/notes.txt
      
      # 忽略 node_modules/ 目录
      node_modules/
      
      # 忽略 .DS_Store 文件(macOS 系统文件)
      .DS_Store
      
  • 注意事项

    • .gitignore 对已跟踪的文件无效:如果文件已经被 Git 跟踪,.gitignore 不会生效。需要先使用 git rm --cached 移除跟踪。
    • 规则顺序:规则的顺序很重要,后面的规则可能会覆盖前面的规则。

Git常用命令

git diff

  • 工作区中已修改但未暂存的文件与暂存区中的文件的差异(工作区与暂存区

    • git diff
      
  • 查看暂存区中的文件与最新提交(HEAD)中的文件的差异(暂存区与最新提交

    • git diff --cached
      或者
      git diff --staged
      
  • 查看工作区与暂存区中的文件与最新提交(HEAD)中的文件的差异(工作区和暂存区与最新提交

    • git diff HEAD
      
  • 查看两个提交之间的差异:

    • git diff <commit-id> <commit-id>
      
  • 查看两个分支之间的差异:

    • git diff <分支1> <分支2>
      
  • 查看某个文件在不同版本之间的差异:

    • git diff <commit-id> <commit-id> -- <文件名>
      
      git diff HEAD^ HEAD -- file.txt
      
  • 查看差异的统计信息(如更改的文件数量和行数):

    • git diff --stat
      

git diff 的输出展示了文件之间的差异,格式为统一的 diff 格式。

  • git diff 输出通常包括以下几个部分:

    • 文件头:描述被比较的文件。
    • 块头:描述差异的具体位置。
    • 差异内容:显示具体的行变化。
  • 文件头格式如下:

    • diff --git a/file1.txt b/file1.txt
      index 1234567..89abcde 100644
      
    • diff --git a/file1.txt b/file1.txt:比较的是 a/file1.txt(旧文件)和 b/file1.txt(新文件)。

    • index 1234567..89abcde 100644:文件的索引信息,1234567 是旧文件的哈希,89abcde 是新文件的哈希,100644 是文件模式。

  • 块头格式如下

    • @@ -1,5 +1,6 @@
      
    • @@ -1,5 +1,6 @@:表示旧文件从第 1 行开始的 5 行,与新文件从第 1 行开始的 6 行有差异。

  • 差异内容

    • 差异内容用符号标记变化:
      • -:删除的行(旧文件中的行)。
      • +:新增的行(新文件中的行)。
      • 没有符号:未更改的行。
  • 完整示例

    • diff --git a/file1.txt b/file1.txt
      index 1234567..89abcde 100644
      --- a/file1.txt
      +++ b/file1.txt
      @@ -1,5 +1,6 @@
       Hello, world!
      -This is the old line.
      +This is the new line.
      +This is an additional line.
       The rest of the file
       remains unchanged.
       Another line.
      
    • 文件头

      • 比较 a/file1.txtb/file1.txt
      • 旧文件哈希为 1234567,新文件哈希为 89abcde
    • 块头

      • 旧文件从第 1 行开始的 5 行与新文件从第 1 行开始的 6 行有差异。
    • 差异内容

      • Hello, world!:未更改。
      • -This is the old line.:删除的行。
      • +This is the new line.:新增的行。
      • +This is an additional line.:新增的行。
      • The rest of the fileremains unchanged.:未更改。
      • Another line.:未更改。

git rm

  • 使用rm命令只会从工作区删除文件,不会将该操作添加到暂存区

  • 使用 git rm 命令可以从工作区和暂存区同时删除文件

    • git rm filename
      
    • 效果

      • 从工作区删除文件。
      • 将删除操作添加到暂存区。
  • 提交删除操作

    • 删除文件后,需要提交更改以更新本地仓库:

    • git commit -m "Delete filename"
      
  • 如果只想从仓库中取消跟踪文件但保留在工作区,可以使用 git rm --cached

    • git rm --cached filename
      
    • 效果

      • 从暂存区和仓库中移除文件:文件不再被 Git 跟踪。
      • 不影响本地仓库的历史记录:文件仍然存在于之前的提交中,但未来的提交将不再包含该文件
      • 保留文件在工作区:文件仍然保留在你的本地文件系统中,不会被删除。
      • 执行 git rm --cached 后,必须提交更改才能真正从未来的提交中移除文件。
  • 如果需要删除目录及其内容,使用 -r 选项:

    • git rm -r directoryname
      
    • 提交删除操作即可

分支

概念

  • Git 分支是 Git 的核心功能之一,它允许你在同一个仓库中并行开发多个功能或版本
  • 分支:分支是代码的独立开发线,允许你在不影响主线(如 mainmaster)的情况下进行开发。
  • 默认分支:通常为 mainmaster,是项目的主线。
  • 特性分支:用于开发新功能或修复 bug 的分支。

命令

  • 查看本地分支

    • git branch
      
    • 当前分支前会有一个 * 标记。

  • 查看所有分支(包括远程分支)

    • git branch -a
      
  • 创建新分支

    • git branch <branch-name>
      
  • 切换分支

    • git switch <branch-name>
      
  • 删除本地分支

    • git branch -d <branch-name>
      
    • 这回删除已经进行合并的分支,如果分支未合并,使用 -D 强制删除

  • 合并分支

    • 合并分支到当前分支

      • git merge <branch-name>
        
      • 如果发生冲突则手动打开文件进行修改后保存并提交

    • 变基是将当前分支的提交“移植”到目标分支的最新提交之后。

      • 找到共同的父节点,将该分支单独形成的节点接到目标分支之后

      • git rebase <target-branch>
        
  • 查看分支的提交历史

    • git log <branch-name>
      
  • 查看分支的图形化历史

    • git log --graph --oneline --all
      
  • 推送本地分支到远程仓库

    • git push origin <branch-name>
      
  • 拉取远程分支的更新

    • git pull origin <branch-name>
      

总结

命令 说明
git branch 查看本地分支
git branch -a 查看所有分支(包括远程分支)
git branch <branch-name> 创建新分支
git checkout -b <branch-name> 创建并切换到新分支
git checkout <branch-name> 切换到已有分支
git branch -d <branch-name> 删除本地分支
git push origin --delete <branch-name> 删除远程分支
git merge <branch-name> 合并分支到当前分支
git rebase <target-branch> 变基到目标分支
git push origin <branch-name> 推送本地分支到远程仓库
git pull origin <branch-name> 拉取远程分支的更新

远程仓库

连接远程仓库

  • 创建远程仓库(GitHub、Gitee)等

  • 配置配置 Git 的用户名和邮箱,这些信息会记录在每次提交中。

    • git config --global user.name "Your Name"
      git config --global user.email "your.email@example.com"
      
  • 查看配置

    • git config --list
      
  • 生成 SSH 密钥(推荐)

    • SSH 是一种安全的连接方式,可以避免每次操作时输入密码。

    • 生成 SSH 密钥对

      • ssh-keygen -t rsa -b 4096 -C "your.email@example.com"
        
      • 会生成公钥和私钥

    • 将公钥添加到远程仓库(如 GitHub、GitLab)的 SSH 密钥设置中。

  • 测试 SSH 连接

    • ssh -T git@github.com
      
    • 不用修改上面测试命令,如果配置正确,会显示认证成功的消息。

  • SSH 密钥的工作原理

    • 生成密钥对
      • 使用 ssh-keygen 生成一对公钥和私钥。
      • 私钥保存在本地,公钥上传到远程服务器或 Git 托管平台。
    • 身份验证过程
      • 当你尝试连接远程服务器或 Git 托管平台时,远程服务器会生成一个随机字符串,并用你的公钥加密。
      • 加密后的字符串发送到你的本地计算机。
      • 你的本地计算机使用私钥解密字符串,并将解密结果发送回远程服务器。
      • 如果解密结果正确,远程服务器确认你的身份,允许访问。

常用命令

查看远程仓库信息

  • 查看所有远程仓库的别名和 URL

    • git remote -v
      
    • origin  git@github.com:username/repository.git (fetch)
      origin  git@github.com:username/repository.git (push)
      upstream  git@github.com:otheruser/repository.git (fetch)
      upstream  git@github.com:otheruser/repository.git (push)
      
    • originupstream 是远程仓库的别名。

    • fetchpush 分别表示拉取和推送的 URL。

  • 查看某个远程仓库的详细信息

    • git remote show origin
      
  • 查看所有远程分支

    • git branch -r
      
  • 查看所有分支(包括本地和远程)

    • git branch -a
      
  • 查看远程分支的提交历史

    • git log origin/main
      
      • origin/main 为想查看的远程分支。

拷贝代码

  • git clone 用于将远程仓库的代码完整地下载到本地。

    • git clone <repository-url>
      
    • <repository-url>:远程仓库的 URL(可以是 SSH 或 HTTPS)。

    • 默认会将远程仓库克隆到当前目录下的同名文件夹中。

  • 克隆特定分支

    • git clone -b <branch-name> <repository-url>
      
      • <branch-name>:远程仓库的分支名称。
  • 拉取远程仓库的更新

    • git pull

      • git pullgit fetchgit merge 的组合,用于拉取远程分支的更新并合并到当前分支。

      • git pull origin <branch-name>
        
      • origin:远程仓库的别名。

      • <branch-name>:远程分支名称。

      • git pull 默认会拉取远程分支的更新并自动合并到当前分支。如果存在冲突,需要手动解决。

    • git fetch 用于从远程仓库下载最新的代码,但不会自动合并到当前分支。

      • 拉取所有远程分支的更新
        git fetch --all
        拉取特定远程分支的更新
        git fetch origin <branch-name>
        
    • 如果使用 git fetch 拉取了更新,可以手动合并到当前分支:

      • git merge origin/<branch-name>
        
  • 拉取更新后,可以使用以下命令查看远程分支的状态:

    • 查看远程分支的更新

      • git log origin/<branch-name>
        
  • 解决冲突

    • 在拉取或合并远程分支时,可能会遇到冲突。解决冲突的步骤如下:

      • 拉取远程分支

      • 打开冲突文件,手动解决冲突。

      • 添加解决冲突后的文件

      • 提交合并

      • git pull origin main
        git add <file>
        git commit
        
posted @ 2025-03-26 18:13  QAQ001  阅读(62)  评论(0)    收藏  举报