Git重写项目历史

Git重写项目历史

BY 童仲毅(geeeeeeeeek@github)

这是一篇在原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名(CC BY 2.5 AU)协议共享。

概述

Git 的主要职责是保证你不会丢失提交的修改。但是,它同样被设计成让你完全掌控开发工作流。这包括了让你自定义你的项目历史,而这也创造了丢失提交的可能性。Git 提供了可以重写项目历史的命令,但也警告你这些命令可能会让你丢失内容。

这份教程讨论了重写提交快照的一些常见原因,并告诉你如何避免不好的影响。

git commit –amend

git commit --amend 命令是修复最新提交的便捷方式。它允许你将缓存的修改和之前的提交合并到一起,而不是提交一个全新的快照。它还可以用来简单地编辑上一次提交的信息而不改变快照。

Git Tutorial: git commit –amend

但是,amend 不只是修改了最新的提交——它进行了一次替换。对于 Git 来说,这看上去像一个全新的提交,即上图中用星号表示的那一个。在公共仓库工作时一定要牢记这一点。

git commit --amend用法

git commit --amend

合并缓存的修改和上一次的提交,用新的快照替换上一个提交。缓存区没有文件时运行这个命令可以用来编辑上次提交的提交信息,而不会更改快照。

讨论

仓促的提交在你日常开发过程中时常会发生。很容易就忘记了缓存一个文件或者弄错了提交信息的格式。--amend 标记是修复这些小意外的便捷方式。

不要修复公共提交

在git reset这节中,我们说过永远不要重设和其他开发者共享的提交。对于修复也是一样:永远不要修复一个已经推送到公共仓库中的提交。

修复过的提交事实上是全新的提交,之前的提交会被移除出项目历史。这和重设公共快照的后果是一样的。如果你修复了其他开发者在之后继续开发的一个提交,看上去他们的工作基础从项目历史中消失了一样。对于在这上面的开发者来说这是很困惑的,而且很难恢复。

例子

下面这个🌰展示了 Git 开发工作流中的一个常见情形。我们编辑了一些希望在同一个快照中提交的文件,但我们忘记添加了其中的一个。修复错误只需要缓存那个文件并且用 --amend 标记提交:

# 编辑 hello.py 和 main.py
git add hello.py
git commit

# 意识到你忘记添加 main.py 的更改
git add main.py
git commit --amend --no-edit

编辑器会弹出上一次提交的信息,加入 --no-edit 标记会修复提交但不修改提交信息。需要的话你可以修改,不然的话就像往常一样保存并关闭文件。完整的提交会替换之前不完整的提交,看上去就像我们在同一个快照中提交了 hello.py 和 main.py。

Git保持同步

Git保持同步

BY 童仲毅(geeeeeeeeek@github)

这是一篇在原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名(CC BY 2.5 AU)协议共享。

SVN 使用唯一的中央仓库作为开发者之间沟通的桥梁,在开发者的工作拷贝和中央仓库之间传递变更集合(changeset),协作得以发生。这和Git的协作模型有所不同,Git 给予每个开发者一份自己的仓库拷贝,拥有自己完整的本地历史和分支结构。用户通常共享一系列的提交而不是单个变更集合。Git 允许你在仓库间共享整个分支,而不是从工作副本提交一个差异集合到中央仓库。

下面的命令让你管理仓库之间的连接,将分支「推送」到其他仓库来发布本地历史,或是将分支「拉取」到本地仓库来查看其它开发者的贡献。

git remote

git remote 命令允许你创建、查看和删除和其它仓库之间的连接。远程连接更像是书签,而不是直接跳转到其他仓库的链接。它用方便记住的别名引用不那么方便记住的 URL,而不是提供其他仓库的实时连接。

例如,下图显示了你的仓库和中央仓库以及另一个开发者仓库之间的远程连接。你可以向 Git 命令传递 origin 和 john 的别名来引用这些仓库,替代完整的 URL。

Git Tutorial: git remote

git remote用法

git remote

列出你和其他仓库之间的远程连接。

git remote -v

和上个命令相同,但同时显示每个连接的 URL。

git remote add <name> <url>

创建一个新的远程仓库连接。在添加之后,你可以将 <name> 作为 <url> 便捷的别名在其他 Git 命令中使用。

git remote rm <name>

移除名为的远程仓库的连接。

git remote rename <old-name> <new-name>

将远程连接从 <old-name> 重命名为 <new-name>。

讨论

Git 被设计为给每个开发者提供完全隔离的开发环境。也就是说信息并不是自动地在仓库之间传递。开发者需要手动将上游提交拉取到本地,或手动将本地提交推送到中央仓库中去。git remote 命令正是将 URL 传递给这些「共享」命令的快捷方式。

GitHub发布Release详尽指南

在开发过程中,发布 Release 是一个重要的环节,能够有效地管理软件的版本和交付。本文将详细介绍如何在 GitHub 上发布 Release,包括操作步骤、注意事项及常见问题解答。

什么是GitHub Release

GitHub Release 是 GitHub 提供的一项功能,用于管理项目的发布版本。每一个 Release 都可以附带二进制文件、源代码压缩包以及变更日志,方便用户下载和使用。通过 Release,开发者能够清晰地展示项目的进展,并为用户提供稳定的版本。

为什么要在 GitHub 上发布 Release

  • 版本管理:使用 Release 可以帮助开发者对项目进行有效的版本管理。
  • 便于用户下载:用户可以轻松找到适合自己的版本进行下载。
  • 信息透明:Release 说明可以让用户了解到版本更新的内容与改动。

如何在 GitHub 上发布 Release

第一步:准备工作

在发布 Release 之前,需要确保你的项目已经完成了相应的功能开发和测试。

  • 确保代码稳定:确认你的代码已经经过充分测试,能够正常运行。
  • 更新文档:确保项目的文档(如 README 文件)是最新的,并且描述了新版本的主要特性。

第二步:创建 Tag

  1. 登录到你的 GitHub 账号,进入需要发布 Release 的项目页面。
  2. 点击页面上方的 “Code” 选项卡。
  3. 在页面右侧,找到 “Releases” 链接,点击进入。
  4. 点击 “Draft a new release” 按钮。
  5. 在 “Tag version” 输入框中输入新的 Tag 名称(例如 v1.0.0)。
  6. 选择相应的基础分支(通常是 main 或 master)。

第三步:填写 Release 信息

在创建 Release 页面中,需要填写一些关键信息:

Git实用命令详解

  1. 将本地项目推送到远程仓库
git init(初始化)
git remote -v (查看已经关联的地址)
git add . (添加本地仓库)
git commit -m "第一次提交"(提交说明)
git remote add origin xxx(关联远程仓库)
git pull --rebase origin master(同步本地与远程仓库)
git push -u origin master(提交远程仓库)-f:强制推送至远程
  1. Git回退到某个历史版本

找到要回退的版本号(右击项目–> Git –> Show History –>选中要回退的版本–>Copy Revision Number)

git reset --hard 139dcfaa558e3276b30b6b2e5cbbb9c00bbdca96  (后面为版本号)
  1. 把修改推到远程服务器
git push -f -u origin master 或者  git push -f 强制同步远程仓库。
  1. 修改项目关联远程地址方法

修改命令

git remote set-url origin <url>

手动修改

项目.git文件夹下,编辑config配置文件中url

  1. Git 修改分支的名称

需要将分支br_rename_old修改为br_rename_new,执行如下步骤:

  • 执行命令git checkout br_rename_old切换到br_rename_old分支,如果已经在这个分支下,可以不执行此步骤
  • 执行命令git pull origin br_rename_old将代码更新到和远程仓库一致
  • 执行命令git branch -m br_rename_old br_rename_new将本地仓库的br_rename_old的名称修改为br_rename_new
  • 执行命令git push --set-upstream origin br_rename_new将本地分支push到远程仓库
  • 执行命令git push origin --delete br_rename_old将远程分支br_rename_old删除
  1. Git 删除分支

我现在在dev20181018分支上,想删除dev20181018分支

修改Git远程URL

查看当前远端地址

$ git remote -v
origin  ssh://ov@git.zjq.xyz:29/ex.git (fetch)
origin  ssh://ov@git.zjq.xyz:29/ex.git (push)

修改新的远端地址

git remote set-url origin ssh://vo@git.jidan.org:29/ex.git

验证修改结果

$ git remote -v
origin  ssh://vo@git.jidan.org:29/ex.git (fetch)
origin  ssh://vo@git.jidan.org:29/ex.git (push)

下来就可以Push最新修改

On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
The authenticity of host '[git.jidan.org]:29 ([8.8.8.8]:29)' can't be established.
ED25519 key fingerprint is SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:6: [git.zjq.xyz]:29
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[git.jidan.org]:29' (ED25519) to the list of known hosts.
Enumerating objects: 39, done.
Counting objects: 100% (39/39), done.
Delta compression using up to 4 threads
Compressing objects: 100% (23/23), done.
Writing objects: 100% (23/23), 10.86 MiB | 3.13 MiB/s, done.
Total 23 (delta 4), reused 0 (delta 0), pack-reused 0 (from 0)
To ssh://git.jidan.org:29/ex.git
   17ae34c..b8ae5da  master -> master
Push Done!

AI生成

如何最简便的搭建Git服务?

假设你有个绑定域名为git.gitfaq.cn的服务器,并且可以通过SSH登录,计划将所有仓库(repository)放到/data/git目录中。

建立仓库(repository)

本地新建仓库(repository)

mkdir repo.git
git init

将仓库(repository)上传到服务器中。

scp -r repo.git user@git.gitfaq.cn:/data/git

成功后,即可通过user@git.gitfaq.cn:/data/git/repo.git来访问远端仓库。

访问仓库(repository)

建立好仓库后,拥有SSH权限的user就可以对user@git.gitfaq.cn:/data/git/repo.git拥有操作权限。

还可以通过git init --shared设置仓库目录的组权限为可写,此命令不会影响任何提交、引用等内容。

ssh user@git.gitfaq.cn
cd /data/git/repo.git
git init --bare --shared

如果需要多个用户都对仓库有读写权限,又不能给每个用户在服务器上建立账户,那么提供 SSH 连接就是唯一的选择。 假设用来共享仓库的服务器已经安装了 SSH 服务,而且你通过它访问服务器。

以下几个方法可以使你给团队每个成员提供访问权:

  • 给每个人创建账号,为每个人运行一次 adduser(或者 useradd)并且设置密码。
  • 在主机上建立一个 git 公用账户,每个需要权限的人发一个 SSH 公钥, 然后将其加入 git 账户的 ~/.ssh/authorized_keys 文件。 这样一来,所有人都将通过 git账户访问主机。
  • 让 SSH 服务器通过某个 LDAP 服务,或者其他已经设定好的集中授权机制,来进行授权。 只要每个用户可以获得主机的 shell 访问权限,任何 SSH 授权机制你都可视为是有效的。

AI生成

初次使用 Git 的一些配置

安装完Git,你会想要做几件事来定制你的 Git 环境。 每台计算机上只需要配置一次,程序升级时会保留配置信息。 你可以在任何时候再次通过运行命令来修改它们。

git配置管理

Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。 这些变量存储在三个不同的位置:

  • /etc/gitconfig 文件: 包含系统上所有用户及他们仓库的通用配置。 如果在执行 git config 时带上 --system 选项,那么它就会读写该文件中的配置变量。 (需要管理员或超级用户权限)

  • ~/.gitconfig 或 ~/.config/git/config 文件:只针对当前用户。 你可以传递 --global 选项让 Git 读写此文件,这会对你系统上 所有 的仓库生效。

  • 当前使用仓库的 Git 目录中的 config 文件(即 .git/config):针对当前仓库。 你可以传递 --local 选项让 Git 强制读写此文件,虽然默认情况下用的就是它。 (需要进入某个 Git 仓库中才能让该选项生效。)

每一个级别会覆盖上一级别的配置,所以 .git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量。

在 Windows 系统中,Git 会查找 $HOME 目录下(一般情况下是 C:\Users$USER )的 .gitconfig 文件。 Git 同样也会寻找 /etc/gitconfig 文件,但只限于 MSys 的根目录下,即安装 Git 时所选的目标位置。 如果你在 Windows 上使用 Git 2.x 以后的版本,那么还有一个系统级的配置文件,Windows XP 上在 C:\Documents and Settings\All Users\Application Data\Git\config ,Windows Vista 及其以后的版本在 C:\ProgramData\Git\config 。此文件只能以管理员权限通过 git config -f <file> 来修改。

zsh中使用git的一些配置建议

Zsh 为 Git 提供了一个 Tab 补全库。 想要使用它,只需在你的 .zshrc 中执行 autoload -Uz compinit && compinit 即可。 相对于 Bash,Zsh 的接口更加强大:

$ git che<Tab>
check-attr        -- 显示 gitattributes 信息
check-ref-format  -- 检查引用名称是否符合规范
checkout          -- 从工作区中检出分支或路径
checkout-index    -- 从暂存区拷贝文件至工作目录
cherry            -- 查找没有被合并至上游的提交
cherry-pick       -- 从一些已存在的提交中应用更改

有歧义的 Tab 补全不仅会被列出,它们还会有帮助性的描述,你可以通过不断敲击 Tab 以图形方式浏览补全列表。 该功能可用于 Git 命令、它们的参数和在仓库中内容的名称(例如 refs 和 remotes),还有文件名和其他所有 Zsh 知道如何去补全的项目。

Zsh 提供了一个从版本控制系统中获取信息的框架,叫做 vcs_info 。 把如下代码添加至你的 ~/.zshrc 文件中,就可以在右侧显示分支名称:

autoload -Uz vcs_info
precmd_vcs_info() { vcs_info }
precmd_functions+=( precmd_vcs_info )
setopt prompt_subst
RPROMPT=\$vcs_info_msg_0_
# PROMPT=\$vcs_info_msg_0_'%# '
zstyle ':vcs_info:git:*' formats '%b'

当你的命令行位于一个 Git 仓库目录时,在任何时候,都可以在命令行窗口右侧显示当前分支。 (当然也可以在左侧显示,只需把上面 PROMPT 的注释去掉即可。) 它看起来像这样:

为什么windows下文本文件被检测为二进制文件?

当您将文本文件存储为 UTF-8 时,Git 效果最佳。Windows 上的许多程序都支持 UTF-8,但有些程序不支持,并且仅使用小端 UTF-16 格式,Git 将其检测为二进制文件。如果您无法在程序中使用 UTF-8,则可以指定一个工作树编码,指示应使用哪个编码签出您的文件,同时仍将这些文件作为 UTF-8 存储在存储库中。这允许像 git-diff这样的工具按预期工作,同时仍允许您的工具工作。

为此,您可以使用具有 working-tree-encoding 属性的 gitattributes 模式。例如,以下模式将所有 C 文件设置为使用 UTF-16LE-BOM,这是 Windows 上常见的编码

*.c	working-tree-encoding=UTF-16LE-BOM

您需要运行 git add --renormalize 以使其生效。请注意,如果您在跨平台使用的项目上进行这些更改,您可能希望在按用户配置的文件中或在 $GIT_DIR/info/attributes 中进行更改,因为在存储库中的 .gitattributes 文件中进行更改将适用于存储库的所有用户。

另请参阅以下条目以获取有关规范换行符的信息,并参阅 gitattributes以获取有关属性文件的更多信息。

via https://gitfaq.org/1/01/how-do-i-add-only-a-portion-of-a-file/

AI生成

为什么我有一个总是被修改的文件?

在内部,Git 始终将文件名存储为字节序列,并且不执行任何编码或大小写转换。但是,Windows 和 macOS 默认情况下都对文件名执行大小写转换。因此,最终可能会出现多个文件或目录,其名称仅在大小写上有所不同。Git 可以很好地处理这种情况,但文件系统只能存储其中一个文件,因此当 Git 读取另一个文件以查看其内容时,它看起来已被修改。

最好删除其中一个文件,以便您只有一个文件。您可以使用以下命令(假设在其他干净的工作树上存在两个文件 AFile.txt 和 afile.txt)执行此操作

$ git rm --cached AFile.txt
$ git commit -m 'Remove files conflicting in case'
$ git checkout .

这样可以避免接触磁盘,但会删除附加文件。你的项目可能更喜欢采用命名约定,例如全小写名称,以避免此问题再次发生;可以使用pre-receive钩子或作为持续集成 (CI) 系统的一部分来检查此类约定。

如果你的系统正在使用污点或清理过滤器,但之前已提交文件而未运行污点或清理过滤器,则任何平台上都可能出现永久修改的文件。要解决此问题,请在其他干净的工作树上运行以下内容

$ git add --renormalize .

via https://git.js.cn/docs/gitfaq

AI生成