Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

git - Commit directly to a bare repository

Some Context

what this fits into

A collaboration focused web application that offers git hosting (as bare repos)

what we want to do

Allow users to add a set of files directly to their existing repositories.

My Question

Is there a tool or method to manually create a commit that only involves adding new files to a git repo?

We're able to do this now using temporary server-side sparse checkouts but we would like to optimize this process.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The plumbing and porcelain page sort of have an example of this, but I'll try to simplify it.

It seems bare repos still have an index, which can be manipulated and made into a commit. It's probably also possible to create tree object from scratch, but I'm not aware of exactly how.

You probably have to lock the repository if there's a risk someone else might access it at the same time. I'll simply use lockfile from the procmail package here.

#!/bin/bash
cd myrepo.git

MY_BRANCH=master
MY_FILE_CONTENTS=$'Hello, world!
'

# Note this is just a lock for this script. It's not honored by other tools.
lockfile -1 -r 10 lock || exit 1

PARENT_COMMIT="$(git show-ref -s "$MY_BRANCH")"

# Empty the index, not sure if this step is necessary
git read-tree --empty

# Load the current tree. A commit ref is fine, it'll figure it out.
git read-tree "${PARENT_COMMIT}"

# Create a blob object. Some systems have "shasum" instead of "sha1sum"
# Might want to check if it already exists. Left as an excercise. :)
BLOB_ID=$(printf "blob %d%s" $(echo -n "$MY_FILE_CONTENTS" | wc -c) "$MY_FILE_CONTENTS" | sha1sum | cut -d ' ' -f 1)
mkdir -p "objects/${BLOB_ID:0:2}"
printf "blob %d%s" $(echo -n "$MY_FILE_CONTENTS" | wc -c) "$MY_FILE_CONTENTS" | perl -MCompress::Zlib -e 'undef $/; print compress(<>)' > "objects/${BLOB_ID:0:2}/${BLOB_ID:2}"

# Now add it to the index.
git update-index --add --cacheinfo 100644 "$BLOB_ID" "myfile.txt"

# Create a tree from your new index
TREE_ID=$(git write-tree)

# Commit it.
NEW_COMMIT=$(echo "My commit message" | git commit-tree "$TREE_ID" -p "$PARENT_COMMIT")

# Update the branch
git update-ref "refs/heads/$MY_BRANCH" "$NEW_COMMIT" "$PARENT_COMMIT"

# Done
rm -f lock

It'd be nice if there were git commands to create blobs, but I didn't find one. The perl command was taken from another question.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...