zoukankan      html  css  js  c++  java
  • 重写Azure DevOps Server (TFS)中的Git版本记录

    Contents
    1. 概述
    2. 应用场景一:修改某开发人员的电子邮件
    3. 应用场景二:删除服务器中的大文件
    4. 用户场景三:整理代码库的目录结构
    4. 常见问题
       1. 系统提示 ! [rejected] ,没有权限
       2. 其他开发人员拉取(PULL)代码时,出现错误refusing to merge unrelated histories
       3. 重写服务器上的提交记录后,其他成员应该怎么办?
       4. 在所有分支中删除文件,需要增加参数 --all
       5. 错误:Cannot create a new backup

    1. 概述

    一般情况下,提交到了服务器中的版本记录,是不允许修改的。这也是为什么在使用Azure DevOps Server (之前名为TFS)的时候,当我们已经将本地提交(Commit)推送到了服务器上,Azure DevOps Server 找不到在线修改服务器历史记录的方法;如果确实需要修改代码库的历史记录,例如修改提交人、删除大文件等,就需要使用Git的相关命令行功能。本文介绍如何使用git的filter-branch 工具在Azure DevOps Server 中重写服务器端的提交记录。实际上,本文中介绍的方法也适用于大部分Git服务器,例如Github和GitLab等。

    filter-branch 有三个常用的参数:
    1. --tree-filter
    这个选项在检出(checkout)项目的每一个提交后运行指定的命令然后重新提交结果。
    例如,在后面的演示场景中,我们要移除代码库中一个大文件视频,就是使用了这个参数。
    2. --subdirectory-filter
    这个选项使一个子目录做为新的根目录,例如从svn导入过来的代码库,需要去掉tag/release等文件夹,使用trunk作为根目录
    3. --commit-filter
    遍历符合条件的提交,执行指定命令修改代码库,并将修改后的代码提交到代码库,实现重写记录的目标

    前提条件:

    1. 警告:一般在提交记录没有推送到服务器之前,我们可以重写提交记录;一旦提交记录已经推送到了服务器,分享给了其他团队成员,不建议修改历史记录,否则会导致历史记录的混乱,甚至有可能导致代码混乱。
    2. 由于涉及到修改服务器端的历史记录,你的操作账户必须具备“强制推送”的权限,即,可以可以重写历史记录。
      在Azure DevOps Server 中,这项权限默认是未设置状态(如下图),一般的用户都不允许重写历史记录。
      image

    2. 应用场景一:修改某开发人员的电子邮件

    场景说明
    在开发过程中,某用户忘记修改本地的用户名称和电子邮箱信息,做了大量的提交,并推送到了服务器,后来发现服务器上显示不正确,需要修改为正确的邮箱地址。如下图,我需要显示自己的中文姓名和邮箱地址

    image

    操作方法

    1. 首先,将代码克隆到本地计算机;如果正在开发的代码库,不需要重复克隆。
    2. 使用Git Bash打开代码库
    3. 在命令行中运行git filter-branch命令,具体目录格式和参数如下
    git filter-branch --commit-filter '
            if [ "$GIT_AUTHOR_EMAIL" = "zhanghongjun@example.com" ];
            then
                    GIT_AUTHOR_NAME="张洪君";
                    GIT_AUTHOR_EMAIL="zhanghongjun@bjgreatsoft.com";
                    git commit-tree "$@";
            else
                    git commit-tree "$@";
            fi' HEAD
    

    image
    4. 使用强制方式推送本地的更改

    git push --force
    

    image
    5. 检查服务器上的更改
    在Repo-提交中查看服务器的历史记录,你会发现用户的姓名已经发生了变化;
    如果你仔细比较提交ID,会发现也发生了变化。

    image

    3. 应用场景二:删除服务器中的大文件

    场景说明
    单用户在提交文件时间,不小心将大文件例如视频推送到了服务器,导致其他用户克隆、更新非常满,流水线运行的速度也明显降低。
    现在我们需要将用户提交的大文件彻底删除。
    操作方法

    1. 克隆代码库到本地
      在下面的这个示例中,由于代码库中存在一个300MB左右的视频文件(a.mp4),克隆的速度明显很慢
      image
    2. 使用--tree-filter参数删除视频文件
    git filter-branch --tree-filter "rm -f a.mp4"
    

    image
    可以看到,Git遍历了当前分支中的所有提交记录,并将每个提交中的视频文件删除,并重新提交;通过这种方式重新修改了提交历史记录。

    1. 使用--force参数将修改后的提交推送到服务器中
    git push origin master --force
    

    推送完成后,如果你比较推送前后的提交历史记录,你会发现ID(sha值)已经发生了变化。

    1. 如果确认这种修改没有问题,可以在filter-branch命令的后面增加--all参数,在所有分支中移除文件,实现完全删除大文件,提高克隆速度的目标。
    git filter-branch --tree-filter "rm -f a.mp4" -- --all
    

    image
    注意,在--all前面添加--
    你会发现执行这次命令后,test分支发生的修改(见上图)

    4. 用户场景三:整理代码库的目录结构

    场景说明
    在代码库中,由于所有文件都是从svn导入过来的,出现了trunk, tags,releases等目录(如下图),需要将trunk文件夹中的内容,移动到根目录中,作为项目开发的根目录。
    image

    操作方法

    1. 首先克隆代码库,方式与上面的描述一样
    2. 使用git filter-branch --subdirectory-filter
    git filter-branch --subdirectory-filter trunk HEAD
    

    image
    可以看到本地工作区的文件夹结构已经发生了变化
    3. 将本地的变更推送(Push)到服务器

    git push --force
    
    1. 验证服务器上的文件已经发生的变化

    2. 如果需要在所有分支上处理文件夹结构,可以使用--all参数,再次强制推送

    git filter-branch --subdiretory-filter trunk -- --all
    

    4. 常见问题

    1. 系统提示 ! [rejected] ,没有权限

    如下图
    image
    解决方案
    一般是服务器中没有为用户配置强制推送的权限,修改权限后问题消失

    2. 其他开发人员拉取(PULL)代码时,出现错误refusing to merge unrelated histories

    错误信息如下图:
    image
    解决方案:
    在git pull 命令下增加参数--allow-unrelated-histories,如下图:

    git pull --allow-unrelated-histories
    

    3. 重写服务器上的提交记录后,其他成员应该怎么办?

    最好的方法是重新克隆代码库,否则会发现日志记录混乱;还可能会不小心将之前的提交又推送到了服务器上。

    4. 在所有分支中删除文件,需要增加参数 --all

    注意:增加--all,并且前面有两个短横线,例如

    git filter-branch --tree-filter "" -- --all
    

    注意,这里有四个短横线,前两个短横线是指定范围的参数,后面是指定的范围--all

    5. 错误:Cannot create a new backup

    如果第二次运行filter-branch,系统会提示错误信息“Cannot create a new backup.”
    这是由于第一次运行filter-branch的时候,系统已经创建了备份,例如:

    git filter-branch  -f --all --tree-filter "rm -f a.mp4"
    

    注意-f参数的位置,不能放到命令的最后面

    ------------------------------------------------------------

    http://www.cnblogs.com/danzhang/  DevOps MVP 张洪君

    ------------------------------------------------------------

  • 相关阅读:
    NativeXml (1):下载、安装、测试
    NativeXml (7):添加属性
    NativeXml (9):读取
    NativeXml (2):对象建立
    NativeXml (3):保存
    NativeXml (6):添加节点
    NativeXml (10):编辑
    NativeXml (5):事件
    博客园现代化建设—用 Entity Framework 与 Json.NET 实现数据的按需更新
    Entity Framework 小知识分享
  • 原文地址:https://www.cnblogs.com/danzhang/p/13245906.html
Copyright © 2011-2022 走看看