118

I am having a strange issue that I can't seem to resolve. Here is what happend:

I had some log files in a github repository that I didn't want there. I found this script that removes files completely from git history like so:

    #!/bin/bash
set -o errexit

# Author: David Underhill
# Script to permanently delete files/folders from your git repository.  To use 
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2

if [ $# -eq 0 ]; then
    exit 0are still
fi

# make sure we're at the root of git repo
if [ ! -d .git ]; then
    echo "Error: must run this script from the root of a git repository"
    exit 1
fi

# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" HEAD

# remove the temporary history git-filter-branch otherwise leaves behind for a long time
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune

I, of course, made a backup first and then tried it. It seemed to work fine. I then did a git push -f and was greeted with the following messages:

error: Unable to append to .git/logs/refs/remotes/origin/master: Permission denied
error: Cannot update the ref 'refs/remotes/origin/master'.

Everything seems to have pushed fine though, because the files seem to be gone from the GitHub repository, if I try and push again I get the same thing:

error: Unable to append to .git/logs/refs/remotes/origin/master: Permission denied
error: Cannot update the ref 'refs/remotes/origin/master'.
Everything up-to-date

EDIT

$ sudo chgrp {user} .git/logs/refs/remotes/origin/master
$ sudo chown {user} .git/logs/refs/remotes/origin/master
$ git push
Everything up-to-date

Thanks!

EDIT

Uh Oh. Problem. I've been working on this project all night and just went to commit my changes:

error: Unable to append to .git/logs/refs/heads/master: Permission denied
fatal: cannot update HEAD ref

So I:

sudo chown {user} .git/logs/refs/heads/master
sudo chgrp {user} .git/logs/refs/heads/master

I try the commit again and I get:

error: Unable to append to .git/logs/HEAD: Permission denied
fatal: cannot update HEAD ref

So I:

sudo chown {user} .git/logs/HEAD
sudo chgrp {user} .git/logs/HEAD

And then I try the commit again:

16 files changed, 499 insertions(+), 284 deletions(-)
create mode 100644 logs/DBerrors.xsl
delete mode 100644 logs/emptyPHPerrors.php
create mode 100644 logs/trimXMLerrors.php
rewrite public/codeCore/Classes/php/DatabaseConnection.php (77%)
create mode 100644 public/codeSite/php/init.php
$ git push
Counting objects: 49, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (27/27), done.
Writing objects: 100% (27/27), 7.72 KiB, done.
Total 27 (delta 15), reused 0 (delta 0)
To git@github.com:IAmCorbin/MooKit.git
59da24e..68b6397  master -> master

Hooray. I jump on http://GitHub.com and check out the repository, and my latest commit is no where to be found. ::scratch head:: So I push again:

Everything up-to-date

Umm...it doesn't look like it. I've never had this issue before, could this be a problem with github? or did I mess something up with my git project?

EDIT

Nevermind, I did a simple:

git push origin master

and it pushed fine.

Corbin Tarrant
  • 1,528
  • 3
  • 14
  • 19

10 Answers10

288

This looks like you ran git as root locally, thus changing ownership on some of the files tracking the location of the origin branch.

Fix the file ownership, and you should be fine:

# run this from the root of the git working tree
sudo chown -R "${USER:-$(id -un)}" .
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 1
    That command worked for me. I ran it from the root of the clone. Thanks @CharlesDuffy! – ariestav Jul 15 '13 at 14:45
  • 5
    @Mr.Stranger, only if you have a sane IFS value and username (usernames with spaces can happen, for instance on cygwin). Safer to quote: `sudo chown -R "$USER" .`, and not assume sanity. :) – Charles Duffy Jan 27 '16 at 15:09
  • @Mr.Stranger, ...also, `USER` isn't guaranteed by http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_03, so it might be safer to use `"$(id -un)"`. – Charles Duffy Jan 27 '16 at 15:13
  • It says my user `is not in the sudoers file. This incident will be reported.` - any tip about what I can do? Thanks. – giovannipds May 08 '17 at 10:27
  • @giovannipds, talk to your sysadmin -- folks with administrative privileges who control your `/etc/sudoers`. Or, if you can log in as root, do that (and chown the fully-qualified path to the relevant file to the target username specifically, as opposed to using `$USER` or `$(id -un)` as the answer here does). – Charles Duffy May 08 '17 at 15:49
  • Thanks anyway, I'm already very far from this case right now. =P – giovannipds Nov 09 '17 at 05:19
  • @Mike6679, which shell? That's a perfectly valid substitution in bash; if your script starts with `#!/bin/sh`, then only POSIX behavior is guaranteed valid, and I'd need to look up the standard to know if this complies. – Charles Duffy Nov 20 '17 at 15:56
  • @CharlesDuffy Can you please explain what is the maeaning for "${USER:-$(id -un)}"? Anyway your answer is working perfectly fine. – N. Karthic Kannan Jun 23 '18 at 07:13
  • 2
    The syntax above is [parameter expansion](http://wiki.bash-hackers.org/syntax/pe); `"${var:-default}"` expands to the value of the variable `"$var"`, *unless* that value is empty or unset, in which case it resolves to `default`. Thus, we either expand to `"$USER"`, or the output generated by running `id -un`. – Charles Duffy Jun 23 '18 at 18:27
  • was not able to make this work using sudo su, i.e. using root user was able to resolve this issue – madan Jan 30 '22 at 04:53
  • @madan, I'd need more details on what you tried that didn't work to be able to describe what went wrong. Maybe ask a new question with reproduction steps? – Charles Duffy Jan 30 '22 at 17:06
  • I just ran this command but the faced another issue as follows [sudo] password for hi-talent: chown: missing operand after ‘hi-talent’ Try 'chown --help' for more information. hi-talent is the username I did not look through it so tried the root user, and was able to work around the issue I tried again the solution you provided and got the mistake I made, previously when I copied the command I missed the . in the end thanks – madan Jan 30 '22 at 17:17
6

Let's concentrate on what it's complaining about exactly:

Permission denied error: Cannot update the ref 'refs/remotes/origin/master'.

Before doing recursive mod/ownership changes, traverse your way to that file and fix any permissions that are incorrect.

I think I caused this issue by creating a branch while I was root and then trying to mess with that branch as my user.

Andrew E
  • 158
  • 2
  • 4
  • 3
    Is fixing the files that are owned by anyone other than the user expected to own the entire source tree one-by-one really an improvement? – Charles Duffy Mar 20 '19 at 11:56
6

you can just do a simple :

sudo chown -R <username> <folder>

replace "username" with the user you want to give access to and the "folder" with the path of the folder relative to where you are executing this command from

This is more of a generic solution to permission issues, but I think this is what should help.

Tegbir Singh
  • 61
  • 1
  • 1
4

In my case I created the files with root permission locally and tried to push the code to remote with local permissions. So I ran this command

$find . -user root

to find out what all files have "root" as owner. And then I changed owner for all the files that are under root to local using following command

$sudo chown parineethat `find . -user root`

Then I was able to push my code from local to remote.

Parineetha
  • 61
  • 2
  • 2
    ```sudo chown parineethat `find . -user root` ``` is unreliable -- won't work right with filenames with spaces. Instead, `sudo find . -user root -exec chown parineethat {} +`. See [BashPitfalls #1](http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29) for relevant discussion. – Charles Duffy Sep 25 '17 at 11:21
2

This will change all your .git files and directories recursively (from root to 1000)and give you a full listing of all the changes made in the terminal.

sudo chown -Rc $UID .git/

Donald L Wilson
  • 1,291
  • 1
  • 8
  • 10
0

I've tried fixing the ownership for Git, but it still doesn't work.

But, I've managed to fix it by creating the local branch with a different name and delete it.

Then, I check out the very same branch name again and it works.

TLDR;

I can't checkout `staging/rc'.

So, I checkout using staging instead that the remote is pointing to `staging/rc'.

And, I delete it and checkout again. But, this time I use staging/rc as my local branch name.

It works and I've no idea why.

Community
  • 1
  • 1
Morgan Koh
  • 2,297
  • 24
  • 24
0

Try stop all git processes.

Watch them:

ps aux | grep git

Kill:

kill git
Demetry Pascal
  • 383
  • 4
  • 15
0

I was using a visual editor for Git (SourceTree) on Windows. Based on the others answers I realized that I need to always open it in Administrator mode and that fixed my issue:

Run SourceTree as administrator

Alin Ciocan
  • 3,082
  • 4
  • 34
  • 47
-1

As already pointed out, it is because the group or user is set incorrectly.

I want to add the information that the following command does not work for hidden folders:

chown -R user:group *

If you use the * then it will fail, you have to set the absolute path of the folder instead, e.g.:

chown -R user:group /srv/www/vhost/project/
Black
  • 18,150
  • 39
  • 158
  • 271
-19

Please first give the permissions from root account like below

chmod -R 777 foldername

after that run the commit command

julian salas
  • 3,714
  • 1
  • 19
  • 20
Viru
  • 165
  • 1
  • 8
  • 7
    This is extremely dangerous -- it gives any account on the system, including a compromised daemon with only "nobody" privileges, write access to your files. System daemons use "nobody" (or other unprivileged accounts) for security-sensitive components *because* the nobody account isn't supposed to be able to do anything too risky even if it's compromised. By letting all users, even nobody, have write access to your files, you're making essential security measures useless. – Charles Duffy Aug 10 '15 at 14:59
  • 1
    If for some reason you wanted your files to be owned by root and writable by a specific non-root user, the safe way to do that (on a system where each user has their own group, as is standard practice) is to `chown -R root:user directory`, and then `chmod -R 775 directory` (or `770`, if other accounts don't need read access either). – Charles Duffy Aug 10 '15 at 15:03
  • 1
    @JasonGlisson, something that "works" only by creating massive security holes is probably something that would be better off staying broken. – Charles Duffy Mar 01 '16 at 05:00
  • 1
    @JasonGlisson, inasmuch as we're providing advice both as and to a community, as a member of that community, what kind and quality of advice we provide is my business as much as anyone else's -- and, as someone who works in security, I'm well-placed to comment on the subject. See initial comment, re: impact. – Charles Duffy Mar 02 '16 at 15:53
  • 1
    @JasonGlisson, ...as for why my advice didn't work for you, I'd need to see details -- a log of the commands run, in order, with a prompt showing current working directory prior to each; text of any errors emitted; etc -- in order to comment; but the place for that discussion would be attached to the answer for which you're reporting bad results, as opposed to here. – Charles Duffy Mar 02 '16 at 15:57