首页  >  文章  >  web前端  >  在 Git 中使用合并

在 Git 中使用合并

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-09-27 12:25:03991浏览

Working with Merge in Git

在本周的博客中,我想在完成有关使用 git merge 的实验后分享我的想法和经验。

Git 合并策略

完成最近专注于使用 Git 的实验后,我对 Git 使用的两种主要合并策略有了更深入的了解:快进和三向递归 (recursive-ort) 合并。

  • 快进合并:当主分支自创建功能分支以来没有新提交时,就会发生这种情况。在这种情况下,Git 只是将主分支指针向前移动到功能分支的最新提交。这种类型的合并不会创建单独的合并提交,使其变得简单且线性。

  • 3 路递归合并:当主分支和功能分支都有不同的提交时,使用此方法。 Git 计算一个共同的祖先并尝试合并两个分支的更改。如果对两个分支中的相同行或文件进行更改,则可能会出现冲突,需要手动解决。最初,我的印象是,跨不同分支修改同一文件时总会发生冲突。但是,只有当两个分支中更改完全相同的代码行时,才会发生冲突。

实验室实现:功能分支合并

在本实验中,我致力于向我的存储库 VShell 添加两个功能,其中涉及为每个功能创建单独的分支。这些功能旨在通过支持多个输入文件/文件夹和流输出来改进工具的功能。

功能 1:支持多个文件和文件夹 - 第 15 期:

第一个功能涉及使该工具能够同时处理多个文件和文件夹路径。以前,该工具仅处理单个文件输入,但通过此增强功能,用户现在可以传递多个文件或目录作为参数。处理目录中的所有文件。

为了实现这一点,我扩展了现有逻辑以递归地迭代文件夹内容,将文件路径转换为绝对路径,并将所有相关文件存储在数组中。相关片段:

files.forEach((file) => {
    // convert a file path to an absolute path
const filePath = path.resolve(file);
...
const directoryFiles = fs
          .readdirSync(filePath)
          .map((f) => path.join(filePath, f));
allFiles = allFiles.concat(directoryFiles);
...
const results = allFiles.map((file) => {
    process.stderr.write(`Debug: Processing file: ${file}. \n`);
    return fs.readFileSync(file, "utf-8");
});
return results.join("\n");
}

此代码确保单个文件和目录中的所有文件都得到相应处理。

功能 2:对标准输出的流式响应 - 第 16 期:

第二个功能为该工具添加了流支持,允许使用 -s/--stream 标志将响应实时输出到 stdout。与之前的实现相比,这是一个重大改进,之前的实现仅将响应写入输出文件或在处理完成后完整显示。

为了实现这一目标,我引入了异步迭代,使用 for wait...of 循环来处理流式传输的数据块。此外,我实时跟踪令牌使用情况,因为令牌信息仅在最终响应块中可用。核心逻辑如下:

if (options.stream) {
// Handle streaming response
const { response, tokenInfo } = await readStream(chatCompletion);
return { response, tokenInfo };
}
async function readStream(stream) {
  let response = "";
  let tokenInfo;
  for await (const chunk of stream) {
    const content = chunk.choices[0]?.delta?.content;
    if (content) {
      process.stdout.write(content);
      response += content;
    }
    // The last chunk will contain the usage information
    if (chunk?.x_groq?.usage) {
      // Retrieve Token Usage from Response
      const usage = chunk?.x_groq?.usage;
      const promptToken = usage?.prompt_tokens || 0;
      const completionToken = usage?.completion_tokens || 0;
      const totalToken = usage?.total_tokens || 0;
      tokenInfo = { promptToken, completionToken, totalToken };
    }
  }
  return { response, tokenInfo };
}

笔记:

实时流方法需要对令牌跟踪进行调整,这与用于非流式响应的更简单方法相反,在非流式响应中可以直接访问使用数据。

对于流式传输,只有在处理循环中的最后一个块后才能访问令牌使用对象。

// The last chunk will contain the usage information
if (chunk?.x_groq?.usage) {
  // Retrieve Token Usage from Response
  const usage = chunk?.x_groq?.usage;
  ...
}

默认情况下,当使用 -s/--stream 标志而不通过 -o/--output 指定输出文件时,响应将被实时流式传输并显示在控制台中。但是,如果用户想要将响应导出到文件,他们可以使用 -o/--output 标志指定输出文件。

合并流程和 Git 合并策略

完成这两个功能后,我启动了合并过程,首先将功能 1 合并到主分支,然后是功能 2。由于这些功能是在单独的文件中开发的,因此在合并过程中没有发生冲突。然而,Git 使用了 ORT 合并策略(Ostensibility Recursive's Twin),这是从 Git 2.34 开始默认的。 ORT策略是对经典递归合并策略的重写,在处理复杂合并场景时提供更好的性能和准确性。

我的最终合并提交哈希是:286e23c

以上是在 Git 中使用合并的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn