在本周的博客中,我想在完成有关使用 git merge 的实验后分享我的想法和经验。
完成最近专注于使用 Git 的实验后,我对 Git 使用的两种主要合并策略有了更深入的了解:快进和三向递归 (recursive-ort) 合并。
快进合并:当主分支自创建功能分支以来没有新提交时,就会发生这种情况。在这种情况下,Git 只是将主分支指针向前移动到功能分支的最新提交。这种类型的合并不会创建单独的合并提交,使其变得简单且线性。
3 路递归合并:当主分支和功能分支都有不同的提交时,使用此方法。 Git 计算一个共同的祖先并尝试合并两个分支的更改。如果对两个分支中的相同行或文件进行更改,则可能会出现冲突,需要手动解决。最初,我的印象是,跨不同分支修改同一文件时总会发生冲突。但是,只有当两个分支中更改完全相同的代码行时,才会发生冲突。
在本实验中,我致力于向我的存储库 VShell 添加两个功能,其中涉及为每个功能创建单独的分支。这些功能旨在通过支持多个输入文件/文件夹和流输出来改进工具的功能。
第一个功能涉及使该工具能够同时处理多个文件和文件夹路径。以前,该工具仅处理单个文件输入,但通过此增强功能,用户现在可以传递多个文件或目录作为参数。处理目录中的所有文件。
为了实现这一点,我扩展了现有逻辑以递归地迭代文件夹内容,将文件路径转换为绝对路径,并将所有相关文件存储在数组中。相关片段:
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"); }
此代码确保单个文件和目录中的所有文件都得到相应处理。
第二个功能为该工具添加了流支持,允许使用 -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 标志指定输出文件。
完成这两个功能后,我启动了合并过程,首先将功能 1 合并到主分支,然后是功能 2。由于这些功能是在单独的文件中开发的,因此在合并过程中没有发生冲突。然而,Git 使用了 ORT 合并策略(Ostensibility Recursive's Twin),这是从 Git 2.34 开始默认的。 ORT策略是对经典递归合并策略的重写,在处理复杂合并场景时提供更好的性能和准确性。
我的最终合并提交哈希是:286e23c
以上是在 Git 中使用合并的详细内容。更多信息请关注PHP中文网其他相关文章!