Skip to content

Git Day 4: The Real World of Permissions

Today's task was the most challenging and realistic yet. What started as a simple "add, commit, push" workflow turned into a deep dive into the interplay between Linux file permissions and Git's security features. I didn't just run three commands; I had to troubleshoot four distinct permission-related failures to get the job done.

This experience was invaluable because it perfectly demonstrated how ownership and privileges are the foundation upon which all other commands succeed or fail.

Table of Contents


The Task

The objective was to perform the first commit to a new Git repository. The steps were: 1. Copy an index.html file from the /tmp directory on the jump host to the cloned Git repository located at /usr/src/kodekloudrepos/blog on the storage server. 2. Add and commit this new file to the local repository. 3. Push the new commit to the master branch of the remote repository (/opt/blog.git).


My Troubleshooting Journey: A Step-by-Step Solution

My path to success involved overcoming four specific failures.

Step 1: The Initial File Transfer

My first step was to copy the file from the jump host to the storage server.

  • Failure 1: scp Permission Denied I initially tried to copy the file directly to its final destination:

    # Run from the jump_host
    scp /tmp/index.html natasha@ststor01:/usr/src/kodekloudrepos/blog/
    
    This failed with Permission denied. The reason was that the destination directory was owned by the root user, and my login user natasha did not have permission to write there.

  • Solution 1: The Two-Stage scp To solve this, I copied the file to a location I did have permission to write to: natasha's home directory.

    # Run from the jump_host
    scp /tmp/index.html natasha@ststor01:
    
    Then, I logged into the storage server and used sudo to move the file to its final destination.
    # Run from ststor01
    ssh natasha@ststor01
    sudo mv index.html /usr/src/kodekloudrepos/blog/
    

Step 2: Committing the File

With the file in place, I moved into the repository to commit it.

cd /usr/src/kodekloudrepos/blog/

  • Failure 2: Git "Dubious Ownership" When I tried to stage the file, Git stopped me with a security warning:

    git add index.html
    # Output: fatal: detected dubious ownership in repository...
    
    This happened because I was running Git as user natasha, but the repository directory was owned by root. Git's modern security features prevent this by default to protect against malicious code.

  • Solution 2: Add a Safety Exception As the error message suggested, I told Git that I trusted this specific directory.

    git config --global --add safe.directory /usr/src/kodekloudrepos/blog
    

  • Failure 3: git commit Permission Denied Even with the safety exception, I still didn't have permission to write to the root-owned .git directory.

    git commit -m "..."
    # Output: fatal: Unable to create '.../.git/index.lock': Permission denied
    

  • Solution 3: Use sudo for Local Git Commands I used sudo to run the add and commit commands as root, which had the necessary permissions.
    sudo git add index.html
    sudo git commit -m "Add initial index file"
    

Step 3: Pushing to the Remote Server

This was the final hurdle.

  • Failure 4: git push Ownership and Permission Errors My attempt to push failed with two errors: another "dubious ownership" error (this time for the remote repo at /opt/blog.git) and a "Could not read from remote repository" error.
    git push origin master
    # Fails with two fatal errors
    
  • Solution 4: Use sudo for the Push The logic was the same. To write to the root-owned remote repository, the push command itself needed to be run as root.
    sudo git push origin master
    
    This final command succeeded, pushing my commit to the central server.

Why Did I Do This? (The "What & Why")

This task demonstrated the fundamental Git workflow for saving and sharing code. - git add (Staging Area): This command adds changes from the working directory to the "staging area." This lets you group related changes together into a single, clean commit, even if you've been working on multiple things. It's like putting items in a box before you seal it. - git commit (Local Repository): This command takes everything in the staging area and creates a permanent snapshot of it in your local repository's history. Each commit has a unique ID and a message explaining the change. The box is now sealed and labeled. - git push (Remote Repository): This command sends your new commits from your local repository to the shared remote repository, making them visible to your teammates. The box has been shipped.


Deep Dive: The True Lesson - Linux Permissions vs. Git

While this was a Git task, the real lesson was about Linux file permissions and ownership. Every single error I encountered was because a command being run by user natasha was trying to access a file or directory owned by root.

  1. scp Failure: natasha can't write to root's directory.
  2. git add Failure ("Dubious Ownership"): Git's security feature protects natasha from root's potentially malicious repository configuration.
  3. git commit Failure: natasha can't write to root's .git/index.lock file.
  4. git push Failure: natasha can't write to root's remote /opt/blog.git repository.

The ultimate solution to all of these problems was to use sudo to escalate my privileges to root for the necessary commands. A better long-term fix would have been to chown the repository to the natasha user, which would have eliminated the need for sudo altogether.


Common Pitfalls

- Ignoring Ownership: The root cause of all my issues. Not checking who owns the files and directories led to the chain of permission errors. - Misunderstanding sudo: Using sudo scp on the source host does not grant elevated privileges on the destination host. - Git's Safety Features: Not being aware of the "dubious ownership" check can be confusing. It's a modern security feature that is important to understand. - Missing Git User Config: If I hadn't configured it before, git commit would have failed because it needs to know the author's name and email. (git config --global user.name "...").


Exploring the Commands Used

- scp [source] [destination]: Securely copies files between hosts over SSH. - sudo mv [source] [destination]: Moves a file with elevated privileges. - git config --global --add safe.directory [path]: Adds a repository path to Git's list of trusted directories. - sudo git add [file]: Stages a file for commit using root privileges. - sudo git commit -m "[message]": Creates a commit with root privileges. - sudo git push origin master: Pushes commits to the remote origin's master branch with root privileges.