0

First, note that this is not a plain 'merge two directories', this is a question about how to keep the merge of said directories updated when the sources change.

Let us say that I have two directories a and b and I want to merge them into c with the following rules:

  • Entries from a must always be in c regardless of their existence or last modified timestamp.
  • Fill the gaps with b.

A simple cp from b to c and overwriting with a where necessary does the job (copies more than necessary, but it is intended to be used only once)

Now, what I want is some way of keeping this updated (as this is intended to be in a Makefile) So, if there is a new file in a, make copies it. If there is a new file in b, make copies it only if it is not already in c. If a file from a is updated, make, updates it in c and if a file from b is updated, it is updated in c only if it came from b but not if it came from a.

I hope I have explained it accurately.

Noxbru
  • 73
  • What have you tried? Why is make the tool you've chosen for this? – mattdm Dec 17 '19 at 14:44
  • I haven't tried much, and right now, I have a rm followed by two copies. It works, but it needs to copy everything even if just a tiny thing changed. cp -u works for the copy from a but only in the cases where the file from b is older than the one in a so it is not fully reliable. makehas been chosen just as a 'wrapper' as this is intended to be used as make update. – Noxbru Dec 17 '19 at 14:52

2 Answers2

0

Simple solution to reach the required state. You can use the following 2 commands:

rsync -auv b/ c/
rsync -av a/ c/

PROS: it works recursively for all sub-directories tree.

CONS: at the period of time from moment you start the first command and until the end of second command execution, some newer files from "b/" having analogue in "a/" can be temporarily placed into "c/", until they are replaced by the correct files from "a/" by second command.

So, the solution is good only if:

  • you need the end result and not care about the "c/" state during sync procedure;
  • if you do not care about some files to be copied extra times.
Yurko
  • 718
0

You can use this Makefile as a start.

I tested it a bit with GNU Make 4.2.1. I don't know if it will work with other Make versions. I know that it will fail if there is a subdirectory in a or b. Maybe there are other pitfalls.

.PHONY: all

SRCA = a
SRCB = b

DEST = c

# create list of targets from wildcard lists of both sources
TARGETS = $(patsubst $(SRCA)/%,$(DEST)/%,$(wildcard $(SRCA)/*)) $(patsubst $(SRCB)/%,$(DEST)/%,$(wildcard $(SRCB)/*)) 

all: $(TARGETS)

# GNU Make prefers the first matching pattern rule because both rules lead to the same stem length 
$(DEST)/%:$(SRCA)/%
    cp "$<" "$@"

# alternative pattern rule if the first one does not match
$(DEST)/%:$(SRCB)/%
    cp "$<" "$@"
Bodo
  • 6,068
  • 17
  • 27