Skip to content

/commands/tar/tar-append-files

tar -rf: add files to an existing tar archive

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · tar (GNU tar) 1.35updated
tool
tar
versions
GNU tar 1.30+, bsdtar 3.x
os
linux, macos, windows

tar -rf archive.tar newfile appends newfile to the end of an existing, uncompressed tar archive. tar -uf archive.tar file (update) appends the file only if it is newer than the copy already in the archive. Neither works on compressed archives: GNU tar stops with Cannot update compressed archives, so decompress first, append, and compress again. Appending never removes the old copy; a name can then appear twice, and extraction leaves the last one on disk.

Example

bash
mkdir -p proj
printf 'v1\n' > proj/notes.txt
touch -d '2020-01-01 00:00' proj/notes.txt
printf 'readme\n' > proj/README.md
tar -cf proj.tar proj/README.md
tar -rf proj.tar proj/notes.txt
tar -tf proj.tar
echo ===
printf 'v2\n' > proj/notes.txt
tar -uf proj.tar proj/notes.txt
tar -tf proj.tar
mkdir out
tar -xf proj.tar -C out
cat out/proj/notes.txt

Output

proj/README.md
proj/notes.txt
===
proj/README.md
proj/notes.txt
proj/notes.txt
v2

-r added notes.txt after README.md. The first copy was stored with a 2020 modification time; after the file was rewritten, -u appended a second copy because its modification time is newer than the stored one, so the listing shows proj/notes.txt twice. Extracting the archive leaves the content of the last copy, v2.

Compressed archives

bash
printf 'a\n' > a.txt
printf 'b\n' > b.txt
tar -czf small.tar.gz a.txt
tar -rf small.tar.gz b.txt

Output · exit 2

tar: Cannot update compressed archives
tar: Error is not recoverable: exiting now

GNU tar refuses to append to a compressed archive and exits with status 2. The workaround is to round-trip through the uncompressed form:

bash
gunzip small.tar.gz          # leaves small.tar
tar -rf small.tar b.txt
gzip small.tar               # back to small.tar.gz

Modes that change an archive

CommandEffect
tar -rf a.tar FILEAppend FILE to the end of a.tar
tar -uf a.tar FILEAppend FILE only if it is newer than the archived copy
tar -Af a.tar b.tarAppend the members of b.tar to a.tar (concatenate, GNU)
tar --delete -f a.tar PATHRemove a member (GNU, uncompressed only)
tar -rf a.tar -C dir FILEAppend FILE as stored relative to dir
tar -cf a.tar FILECreate: replaces the whole archive, does not append

Pitfalls

  • -c instead of -r overwrites the archive with a new one that holds only the new files.
  • Member names must match. -u compares by stored name: if the archive holds proj/notes.txt, updating ./proj/notes.txt or an absolute path appends an unrelated member.
  • cat a.tar b.tar > c.tar is not a valid merge. The end-of-archive blocks of a.tar stay in the middle, and tar stops reading there unless --ignore-zeros is given. Use -A.
  • bsdtar (macOS, Windows tar.exe) supports -r and -u on uncompressed archives; -A and --delete are GNU tar options.

Confirm it worked

tar -tf archive.tar lists every member in order, including duplicates. To see only the last copy of each name, extract into an empty directory and compare it with the source.

FAQ

How do I add a file to a .tar.gz archive?

You cannot append to it directly. Decompress it with gunzip archive.tar.gz, append with tar -rf archive.tar file, and compress again with gzip archive.tar. For frequent additions, keep the archive uncompressed until it is final.

How do I remove a file from a tar archive?

GNU tar has --delete, as in tar --delete -f archive.tar path/in/archive. It works only on uncompressed archives and on regular files, not on tapes. bsdtar has no --delete; recreate the archive without the file instead.

Which copy does tar extract when a name appears twice?

Both are extracted in archive order, so the later copy overwrites the earlier one on disk. The result is the newest appended version, which is how tar -u is meant to work.

Sources