How does `ipfs files` interact with pins?

Does adding a CID to my files pin that content? Does removing it unpin it?

Put another way, if I don’t pin content that appears in ipfs files ls will it get garbage collected?

Suppose I run the following:

CID=$(ipfs add ./myfile.txt)
ipfs files cp /ipfs/$CID /myfile.txt
ipfs files rm /myfile.txt
ipfs repo gc

Since I added the content directly (not via ipfs files) it was pinned automatically, so does removing it from files unpin it?

Is there a convenient way to find all the pinned content that is not available via ipfs files?

First, I want to make sure we’re using commands correctly, and if you want to output the CID from an add command and save to a variable in your terminal (bash/zsh/sh) you will need to pass some additional parameters:

CID=$(ipfs add -q ./myfile.txt)

Second, when calling ipfs add, the pin option (--pin) is defaulted to true… but that is the only reason it is pinned. Adding a file only means it’s “pinned” because we explicitly execute a pin operation when the pin option for ipfs add is true. If the flag was not true by default, the same action would be ipfs add ./myfile.txt && ipfs pin add /ipfs/$CID


Now to answer your questions more directly:

1. Does adding a CID to my files pin that content?

Yes. --pin is set to true by default

2. Does removing it unpin it?

No. You can verify this by doing

FILE_PATH=myfile.txt
CID=$(ipfs add -q $FILE_PATH)
ipfs files cp /ipfs/$CID /$FILE_PATH
ipfs files rm /$FILE_PATH # explicit MFS removal
ipfs files stat --with-local /ipfs/$CID # local size is 100%
ipfs repo gc # explicit garbage collection
ipfs files stat --with-local /ipfs/$CID # local size is 100%

3. Put another way, if I don’t pin content that appears in ipfs files ls will it get garbage collected?

If you have it in MFS fully available locally, it will not be garbage collected.
From the ipfs files --help output:

All files and folders within MFS are respected and will not be deleted
during garbage collections. However, a DAG may be referenced in MFS without
being fully available locally (MFS content is lazy loaded when accessed).
MFS is independent from the list of pinned items (“ipfs pin ls”). Calls to
“ipfs pin add” and “ipfs pin rm” will add and remove pins independently of
MFS. If MFS content that was additionally pinned is removed by calling
“ipfs files rm”, it will still remain pinned.

Also note: when ipfs add calls ipfs pin, it uses --type=recursive which means any children should be pinned, but they’re indirectly pinned. (so you know which CID and content you explicitly wanted to pin)

4. Since I added the content directly (not via ipfs files) it was pinned automatically, so does removing it from files unpin it?

Nope. See example in answer to #2.

5. Is there a convenient way to find all the pinned content that is not available via ipfs files?

First, what is the type of pinned content you’re interested in? I will assume direct and recursive, but not indirect.

I don’t know if there’s a better way to do this, and I just threw this together, but you can do something like:

# get all CIDs for non-indirect pinned content
PINNED_CIDS=$(ipfs pin ls | grep -v 'indirect' | awk '{print $1}' | sort -u )

# get all CIDs for all files in MFS
MFS_CIDS=$(ipfs files ls | xargs -I% sh -c 'ipfs files stat /"%" | head -1' | sort -u)


# Use comm to find the CIDs that are pinned but not in MFS
comm -23 <(echo "$PINNED_CIDS") <(echo "$MFS_CIDS")
1 Like