From 749bb496e8f83efba10ec086a6596b1875fcb612 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 01:59:58 +0000 Subject: [PATCH 1/4] Initial plan From 45ceab0c4e8cc62bf0dc4af553b140c034e965f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 02:03:33 +0000 Subject: [PATCH 2/4] Add breaking change article: TarWriter uses HardLink entries for hard-linked files Fixes #52683 Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- docs/core/compatibility/11.md | 1 + .../11/tarwriter-hardlink-entries.md | 89 +++++++++++++++++++ docs/core/compatibility/toc.yml | 2 + 3 files changed, 92 insertions(+) create mode 100644 docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md diff --git a/docs/core/compatibility/11.md b/docs/core/compatibility/11.md index 8654a6a8b2d52..7f2b92f0f4233 100644 --- a/docs/core/compatibility/11.md +++ b/docs/core/compatibility/11.md @@ -29,6 +29,7 @@ See [Breaking changes in ASP.NET Core 10](/aspnet/core/breaking-changes/10/overv | [Environment.TickCount made consistent with Windows timeout behavior](core-libraries/11/environment-tickcount-windows-behavior.md) | Behavioral change | | [MemoryStream maximum capacity updated and exception behavior changed](core-libraries/11/memorystream-max-capacity.md) | Behavioral change | | [TAR-reading APIs verify header checksums when reading](core-libraries/11/tar-checksum-validation.md) | Behavioral change | +| [TarWriter uses HardLink entries for hard-linked files](core-libraries/11/tarwriter-hardlink-entries.md) | Behavioral change | | [ZipArchive.CreateAsync eagerly loads ZIP archive entries](core-libraries/11/ziparchive-createasync-eager-load.md) | Behavioral change | ## Cryptography diff --git a/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md b/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md new file mode 100644 index 0000000000000..c3391efab5995 --- /dev/null +++ b/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md @@ -0,0 +1,89 @@ +--- +title: "Breaking change: TarWriter uses HardLink entries for hard-linked files" +description: "Learn about the breaking change in .NET 11 where TarWriter writes HardLink entries for files that share the same inode instead of duplicating the file content." +ms.date: 04/03/2026 +ai-usage: ai-assisted +--- + +# TarWriter uses HardLink entries for hard-linked files + +Starting in .NET 11 Preview 3, detects when multiple files are hard-linked to the same inode and writes a `HardLink` entry for subsequent files instead of duplicating the file content. + +## Version introduced + +.NET 11 Preview 3 + +## Previous behavior + +Previously, when creating a tar archive with `TarWriter`, files that were hard-linked to the same inode were treated as separate, independent files. The full file content was duplicated in the archive for each hard-linked file. + +```csharp +using System.Formats.Tar; +using System.IO; + +string filePath1 = "file1.txt"; +string filePath2 = "file2.txt"; + +// Create two hard-linked files. +File.WriteAllText(filePath1, "Hello, world!"); +File.CreateHardLink(filePath2, filePath1); + +using (var stream = File.Create("archive.tar")) +using (var writer = new TarWriter(stream, TarEntryFormat.Pax, leaveOpen: false)) +{ + writer.WriteEntry(filePath1, "file1.txt"); + writer.WriteEntry(filePath2, "file2.txt"); +} +``` + +In the resulting `archive.tar`, both `file1.txt` and `file2.txt` had separate file entries, each containing the full file content. + +## New behavior + +Starting in .NET 11, `TarWriter` detects when multiple files are hard-linked to the same inode and writes a `HardLink` entry for subsequent files instead of duplicating the file content. + +Using the same code as shown in the [Previous behavior](#previous-behavior) section, the resulting `archive.tar` now contains a full file entry for `file1.txt`, while `file2.txt` has a `HardLink` entry pointing to `file1.txt`. + +## Type of breaking change + +This change is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +This change improves the efficiency of tar archives created by the `System.Formats.Tar` library. By using `HardLink` entries for files that share the same inode, the size of the resulting archive is reduced and the hard-link relationships between files are preserved. This behavior is consistent with GNU tar and other widely used tar implementations. + +## Recommended action + +If your application depends on duplicating file content for hard-linked files, set the `HardLinkMode` property to `TarHardLinkMode.CopyContents` in a new `TarWriterOptions` instance to restore the previous behavior: + +```csharp +using System.Formats.Tar; +using System.IO; + +string filePath1 = "file1.txt"; +string filePath2 = "file2.txt"; + +// Create two hard-linked files. +File.WriteAllText(filePath1, "Hello, world!"); +File.CreateHardLink(filePath2, filePath1); + +var options = new TarWriterOptions(TarEntryFormat.Pax) +{ + HardLinkMode = TarHardLinkMode.CopyContents +}; + +using (var stream = File.Create("archive.tar")) +using (var writer = new TarWriter(stream, options, leaveOpen: false)) +{ + writer.WriteEntry(filePath1, "file1.txt"); + writer.WriteEntry(filePath2, "file2.txt"); +} +``` + +Extracting a tar archive that contains `HardLink` entries to a file system without hard link support throws an . Use the new `TarExtractOptions` class to specify whether to extract hard links as hard links or copy them as separate files, which enables extraction to file systems without hard link support. + +## Affected APIs + +- +- +- diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 8dcf0e709440b..ec9f86ad5eda3 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -20,6 +20,8 @@ items: href: core-libraries/11/memorystream-max-capacity.md - name: TAR-reading APIs verify header checksums when reading href: core-libraries/11/tar-checksum-validation.md + - name: TarWriter uses HardLink entries for hard-linked files + href: core-libraries/11/tarwriter-hardlink-entries.md - name: ZipArchive.CreateAsync eagerly loads ZIP archive entries href: core-libraries/11/ziparchive-createasync-eager-load.md - name: Cryptography From 58f6947a01b7d172ad4b4bbeeab6420619e8e24b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 02:32:06 +0000 Subject: [PATCH 3/4] Fix overly long sentences in TarWriter breaking change article Agent-Logs-Url: https://github.com/dotnet/docs/sessions/1a965af5-8df4-4072-a179-4d952413f887 Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- .../core-libraries/11/tarwriter-hardlink-entries.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md b/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md index c3391efab5995..2fe9a3edf0d13 100644 --- a/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md +++ b/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md @@ -7,7 +7,7 @@ ai-usage: ai-assisted # TarWriter uses HardLink entries for hard-linked files -Starting in .NET 11 Preview 3, detects when multiple files are hard-linked to the same inode and writes a `HardLink` entry for subsequent files instead of duplicating the file content. + now detects when multiple files are hard-linked to the same inode. It writes a `HardLink` entry for subsequent files instead of duplicating the file content. ## Version introduced @@ -54,7 +54,7 @@ This change improves the efficiency of tar archives created by the `System.Forma ## Recommended action -If your application depends on duplicating file content for hard-linked files, set the `HardLinkMode` property to `TarHardLinkMode.CopyContents` in a new `TarWriterOptions` instance to restore the previous behavior: +If your application depends on duplicating file content for hard-linked files, you can restore the previous behavior. Set the `HardLinkMode` property to `TarHardLinkMode.CopyContents` in a new `TarWriterOptions` instance: ```csharp using System.Formats.Tar; @@ -80,7 +80,7 @@ using (var writer = new TarWriter(stream, options, leaveOpen: false)) } ``` -Extracting a tar archive that contains `HardLink` entries to a file system without hard link support throws an . Use the new `TarExtractOptions` class to specify whether to extract hard links as hard links or copy them as separate files, which enables extraction to file systems without hard link support. +Extracting a tar archive that contains `HardLink` entries to a file system without hard link support throws an . Use the new `TarExtractOptions` class to specify whether to extract hard links as hard links or copy them as separate files. This enables extraction to file systems without hard link support. ## Affected APIs From a874c4edcd5a362d9348670ae14d3b3836dac9f5 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Tue, 7 Apr 2026 10:36:50 -0700 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../core-libraries/11/tarwriter-hardlink-entries.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md b/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md index 2fe9a3edf0d13..085d25ead9234 100644 --- a/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md +++ b/docs/core/compatibility/core-libraries/11/tarwriter-hardlink-entries.md @@ -40,7 +40,7 @@ In the resulting `archive.tar`, both `file1.txt` and `file2.txt` had separate fi ## New behavior -Starting in .NET 11, `TarWriter` detects when multiple files are hard-linked to the same inode and writes a `HardLink` entry for subsequent files instead of duplicating the file content. +Starting in .NET 11, detects when multiple files are hard-linked to the same inode and writes a entry for subsequent files instead of duplicating the file content. Using the same code as shown in the [Previous behavior](#previous-behavior) section, the resulting `archive.tar` now contains a full file entry for `file1.txt`, while `file2.txt` has a `HardLink` entry pointing to `file1.txt`. @@ -50,11 +50,11 @@ This change is a [behavioral change](../../categories.md#behavioral-change). ## Reason for change -This change improves the efficiency of tar archives created by the `System.Formats.Tar` library. By using `HardLink` entries for files that share the same inode, the size of the resulting archive is reduced and the hard-link relationships between files are preserved. This behavior is consistent with GNU tar and other widely used tar implementations. +This change improves the efficiency of tar archives created by the library. By using entries for files that share the same inode, the size of the resulting archive is reduced and the hard-link relationships between files are preserved. This behavior is consistent with GNU tar and other widely used tar implementations. ## Recommended action -If your application depends on duplicating file content for hard-linked files, you can restore the previous behavior. Set the `HardLinkMode` property to `TarHardLinkMode.CopyContents` in a new `TarWriterOptions` instance: +If your application depends on duplicating file content for hard-linked files, you can restore the previous behavior. Set the property to in a new instance: ```csharp using System.Formats.Tar; @@ -67,7 +67,7 @@ string filePath2 = "file2.txt"; File.WriteAllText(filePath1, "Hello, world!"); File.CreateHardLink(filePath2, filePath1); -var options = new TarWriterOptions(TarEntryFormat.Pax) +var options = new TarWriterOptions { HardLinkMode = TarHardLinkMode.CopyContents }; @@ -80,7 +80,7 @@ using (var writer = new TarWriter(stream, options, leaveOpen: false)) } ``` -Extracting a tar archive that contains `HardLink` entries to a file system without hard link support throws an . Use the new `TarExtractOptions` class to specify whether to extract hard links as hard links or copy them as separate files. This enables extraction to file systems without hard link support. +Extracting a tar archive that contains `HardLink` entries to a file system without hard link support throws an . Use the new class to specify whether to extract hard links as hard links or copy them as separate files. This enables extraction to file systems without hard link support. ## Affected APIs