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.

2
  • What have you tried? Why is make the tool you've chosen for this? Commented Dec 17, 2019 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. Commented Dec 17, 2019 at 14:52

2 Answers 2

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.
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 "$<" "$@"

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.