

Amazon CodeCatalyst 不再向新客戶開放。現有客戶可以繼續正常使用該服務。如需詳細資訊，請參閱[如何從 CodeCatalyst 遷移](migration.md)。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用合併策略來產生套件和指定檔案
<a name="merge-strategies-lm"></a>

您可以使用合併策略來產生具有重新合成的套件，並指定用於自訂藍圖生命週期管理更新的檔案。透過利用重新合成和合併策略，您可以管理更新，並控制在部署期間更新哪些檔案。您也可以撰寫自己的策略，以控制變更如何合併至現有的 CodeCatalyst 專案。

**Topics**
+ [使用重新合成產生檔案](#three-way-merge-lm)
+ [使用合併策略](#vended-merge-strategies-lm)
+ [指定生命週期管理更新的檔案](#specify-files-lm-updates)
+ [撰寫合併策略](#write-merge-strategies-lm)

## 使用重新合成產生檔案
<a name="three-way-merge-lm"></a>

重新合成可以將藍圖產生的原始程式碼與先前由相同藍圖產生的原始程式碼合併，允許將藍圖的變更傳播到現有專案。合併是從 `resynth()`函數跨藍圖輸出套件執行。重新合成會先產生三個套件，代表藍圖和專案狀態的不同層面。它可以使用 `yarn blueprint:resynth`命令在本機手動執行，如果套件不存在，則會建立套件。手動使用套件可讓您在本機模擬和測試重新合成行為。根據預設，藍圖只會跨 下的儲存庫執行重新合成，`src/*`因為只有該部分的套件通常受來源控制。如需詳細資訊，請參閱[重新合成](custom-bp-concepts.md#resynthesis-concept)。
+ `existing-bundle` - 此套件是現有專案狀態的表示。這是由合成運算人工建構的，以提供藍圖內容，說明其要部署到的專案中的內容 （如果有的話）。如果在本機執行重新合成時，此位置已存在任何內容，則會將其重設並視為模擬。否則，它會設定為 的內容`ancestor-bundle`。
+ `ancestor-bundle` - 如果藍圖輸出是使用一些先前選項和/或版本合成，則此套件代表藍圖輸出。如果這是第一次將此藍圖新增至專案，則祖先不存在，因此設定為與 相同的內容`existing-bundle`。在本機，如果此套件已存在於此位置，則會將其視為模擬。
+ `proposed-bundle` - 如果藍圖是使用一些新選項和/或版本合成，則這是模擬藍圖的套件。這是`synth()`由函數產生的相同套件。在本機，一律會覆寫此套件。

每個套件都是在重新合成階段建立，可從 下的藍圖類別存取`this.context.resynthesisPhase`。
+ `resolved-bundle` - 這是最終套件，這是 CodeCatalyst 專案封裝和部署內容的表示。您可以檢視哪些檔案和差異會傳送到部署機制。這是解析三個其他套件之間合併的`resynth()`函數輸出。

三向合併的套用方式是取得 `ancestor-bundle`和 之間的差異，`proposed-bundle`並將其新增至 `existing-bundle`以產生 `resolved-bundle`。所有合併策略都會將檔案解析為 `resolved-bundle`。重新合成會在 期間透過藍圖的合併策略來解析這些套件的觸角，`resynth()`並從結果產生已解析的套件。

## 使用合併策略
<a name="vended-merge-strategies-lm"></a>

您可以使用藍圖程式庫提供的合併策略。這些策略提供解決 [使用重新合成產生檔案](#three-way-merge-lm)區段中提及之檔案的檔案輸出和衝突的方法。
+ `alwaysUpdate` - 一律解析為提議檔案的策略。
+ `neverUpdate` - 一律解析為現有檔案的策略。
+ `onlyAdd` - 當現有檔案不存在時，解析為提議檔案的策略。否則， 會解析為現有的 檔案。
+ `threeWayMerge` - 在現有、提議和常見上階檔案之間執行三向合併的策略。如果檔案無法完全合併，解析的檔案可能包含衝突標記。提供的檔案內容必須經過 UTF-8 編碼，才能產生有意義的輸出。策略會嘗試偵測輸入檔案是否為二進位檔案。如果策略偵測到二進位檔案中的合併衝突，一律會傳回提議的檔案。
+ `preferProposed` - 在現有、提議和常見上階檔案之間執行三向合併的策略。此策略透過選取每個衝突的提議檔案端來解決衝突。
+ `preferExisting` - 在現有、提議和常見上階檔案之間執行三向合併的策略。此策略透過選取每個衝突的現有檔案端來解決衝突。

若要檢視合併策略的原始程式碼，請參閱[開放原始碼 GitHub 儲存庫](https://github.com/aws/codecatalyst-blueprints/blob/main/packages/blueprints/blueprint/src/resynthesis/merge-strategies/merge-strategies.ts#L17)。

## 指定生命週期管理更新的檔案
<a name="specify-files-lm-updates"></a>

在重新合成期間，藍圖會控制變更如何合併到現有的來源儲存庫。不過，您可能不想將更新推送到藍圖中的每個單一檔案。例如，CSS 樣式表之類的範本程式碼旨在為專案特定。如果您未指定其他策略，則三向合併策略是預設選項。藍圖可以透過在儲存庫建構體上指定合併策略，來指定他們擁有哪些檔案，以及他們不擁有哪些檔案。藍圖可以更新其合併策略，並且可以在重新合成期間使用最新的策略。

```
const sourceRepo = new SourceRepository(this, {
      title: 'my-repo',
    });
    sourceRepo.setResynthStrategies([
      {
        identifier: 'dont-override-sample-code',
        description: 'This strategy is applied accross all sample code. The blueprint will create sample code, but skip attempting to update it.',
        strategy: MergeStrategies.neverUpdate,
        globs: [
          '**/src/**',
          '**/css/**',
        ],
      },
    ]);
```

您可以指定多個合併策略，並以最後一個策略為優先。未涵蓋的檔案預設為three-way-merge，類似於 Git。透過 `MergeStrategies` 建構提供數種合併策略，但您可以自行撰寫。提供的策略遵循 [git 合併策略](https://git-scm.com/docs/merge-strategies)驅動程式。

## 撰寫合併策略
<a name="write-merge-strategies-lm"></a>

除了使用其中一個提供的建置合併策略之外，您也可以撰寫自己的策略。策略必須遵循標準策略界面。您必須撰寫策略函數，從 `existing-bundle`、 `proposed-bundle`和 取得檔案的版本`ancestor-bundle`，並將其合併到單一解析的檔案。例如：

```
type StrategyFunction = (
   /**
   * file from the ancestor bundle (if it exists)
   */
    commonAncestorFile: ContextFile | undefined, 
   /**
   * file from the existing bundle (if it exists)
   */
    existingFile: ContextFile | undefined,
   /**
   * file from the proposed bundle (if it exists)
   */ 
    proposedFile: ContextFile | undefined, 
    options?: {}) 
    /**
    * Return: file you'd like in the resolved bundle
    * passing undefined will delete the file from the resolved bundle
    */ 
=> ContextFile | undefined;
```

如果檔案不存在 （未定義），則該檔案路徑不存在於該特定位置套件中。

**範例：**

```
strategies: [
          {
            identifier: 'dont-override-sample-code',
            description: 'This strategy is applied across all sample code. The blueprint will create sample code, but skip attempting to update it.',
            strategy: (ancestor, existing, proposed) => {
                const resolvedfile = ...
                ...
                // do something
                ...
                return resolvedfile
            },
            globs: [
              '**/src/**',
              '**/css/**',
            ],
          },
        ],
```