I have a this to aliases in my .gitconfig file:
setmeld = config --global diff.external git-meld
nomeld = config --global --unset diff.external
That way I can set and unset the visual diff tool meld.
When I issue:
git setmeld
...the following is added to my .gitconfig file:
[diff]
external = git-meld
When I issue:
git setmeld
...the external = git-meld setting is deleted from my .gitconfig file, but the [diff] section header stays.
If I later run git setmeld again my .gitconfig ends up having two [diff] section headers:
[diff]
[diff]
external = git-meld
If I unset and then set again the external git-meld diff tool I end up with this:
[diff]
[diff]
[diff]
external = git-meld
The problem is not because of the aliases. The same happens if I issue the commands by themselves git config --global diff.external git-meld and config --global --unset diff.external.
- Can I avoid that weird behavior?
OS: Ubuntu 12.04.5 LTS
git version: 1.7.9.5
git doesn't like empty sections.
Use the command
git config diff.dummy "dummy line"
You can edit the config to remove the extra [diff] lines, but be careful to save the config file to config.save first. If git finds that the config file is corrupted, it will refuse further commands.
Then set unset cycles will not add more duplicate sections
Your Git is very old (the current version is 2.8+) and you probably should update yours. The bug may be fixed in newer versions (I have not checked).
Meanwhile, though, this seems like a harmless bug: Git is leaving the section header in place even though the entire section is empty, then adding another section header even though there is already an existing section header. Given the way Git scans the file, though, you may repeat a section header (and a setting) as often as you like. For settings that are not cumulative,1 the last setting overrides the earlier ones.
As a rather hacky workaround, you can just set something else so that the section never becomes entirely empty. Any value will do: anything that Git never uses will just sit around unused, keeping the section not-empty.
There is in fact another diff setting you might want to set, though: diff.renameLimit sets the default size of the rename-detection queue for most git diff operations. In some versions, the "default default" is 500, 1000, and 2000 (it has been growing over time). As of the latest upcoming Git, the new default is 0, which means "unlimited" (which really means "use internal maximum"). I have kept mine set to 0 since very early days.
1One example of a cumulative setting is the value(s) for remote.origin.fetch, assuming you have a [remote "origin"] section. Each fetch = ... value in this section is accumulated, and when running git fetch origin, Git runs each reference obtained from that remote through all the mappings to find its local name. If the mapping produces multiple names, Git complains of an error. (Usually there is only one setting anyway, so that there is only one possible output.)
Related
Our Laravel project is using symlinks. Recently when I tried to pull from my colleague's work, I get this message:
CONFLICT (modify/delete): resources/lang/en/validation.php deleted in HEAD and modified in a262067feb430a072c1d3abf2ec500150212ff0f. Version a262067feb430a072c1d3abf2ec500150212ff0f of resources/lang/en/validation.php left in tree.
error: failed to symlink 'resources/lang/en/validation.php': File name too long
Upon trying to git rm the file, I am told it doesn't exist and is deleted in HEAD. Then when I pull I get the same message as above. Upon trying to touch the file and git add the file, and commit and then pull (in order to push my changes to the same branch), I get a similar error message:
CONFLICT (content): Merge conflict in resources/lang/en/validation.php
CONFLICT (modify/delete): resources/lang/en/auth.php deleted in HEAD and modified in a262067feb430a072c1d3abf2ec500150212ff0f. Version a262067feb430a072c1d3abf2ec500150212ff0f of resources/lang/en/auth.php left in tree.
error: failed to symlink 'resources/lang/en/auth.php': File name too long
I have tried to skip-worktree the file, assume-unchanged the file and to change the git config setting via git config --local core.longpaths true to allow long-paths. None have worked. I think it has to do with the symlink, but I haven't run the script yet and so I don't know how this is a barrier to pulling for git.
When I do try to run the symlink, I get this error message:
error: unable to create symlink resources/lang/en/auth.php: File name too long
error: unable to create symlink resources/lang/en/validation.php: File name too long
Long story short, I cannot git pull, and therefore cannot git push. What's the solution? I don't want to git push force it.
Running git pull is just running two Git commands:
First, git pull runs git fetch. This obtains any new commits needed for the second command.
Second, git pull runs ... well, this can be complicated. You are having it run the default, though: git merge.
Usually when git pull fails, one of these two commands that it runs is the one that actually failed. The second command fails more often unless you have a particularly flaky Internet connection. In your case, it's the git merge that failed.
The word failed is usually too strong, really. Most merges do not actually fail. They just stop in the middle of the operation due to a conflict (or two conflicts, in your particular case). But your merge is a little special. It really does have an internal failure, which repeats several times:
error: unable to create symlink resources/lang/en/auth.php: File name too long
error: unable to create symlink resources/lang/en/validation.php: File name too long
This is happening because your OS is placing a hard limit on the length of the target of a symbolic link. As you found:
It seems it was trying to make a symlink out of the content inside the file instead of the file name ...
Git's internal limits are much bigger than your OS's.
A symbolic link is just data, at one level, and that's how Git tends to store it (as a blob object, but one with mode 120000 rather than the normal file mode of 100644 or 100755). At another level, the data will be interpreted as a file name, and that file name tends to have a length limit, such as 1024 or 4096 bytes.
What would git show do?
git show will spill out the contents of the symlink, when pointed to a symbolic-link object.
$ git hash-object -w -t blob /usr/share/misc/termcap
d305cd8e161ecc8a78b0485d1926b9600efc6cb7
$ git update-index --add --cacheinfo 120000,d305cd8e161ecc8a78b0485d1926b9600efc6cb7,crazy
$ git commit -m "add crazy-long symlink"
[master dbb6e35] add crazy-long symlink
1 file changed, 4725 insertions(+)
create mode 120000 crazy
The normal tools will no longer work with this repository (which I made just to hold this crazy-long symlink):
$ git log | sed 's/#/ /'
commit dbb6e35967041fa4b03812866999ea0acd640dce
Author: Chris Torek <chris.torek gmail.com>
Date: Sun Nov 15 19:52:05 2020 -0800
add crazy-long symlink
commit c6e238c122dcd41410e7fdcfaa47ac112e935a35
Author: Chris Torek <chris.torek gmail.com>
Date: Sun Nov 15 19:51:58 2020 -0800
initial commit
$ git checkout HEAD^
This works fine, but trying to check out the second commit fails:
$ git checkout master
error: unable to create symlink crazy: File name too long
D crazy
Previous HEAD position was c6e238c initial commit
Switched to branch 'master'
What happens at this point is that Git simply leaves the symbolic link out of the working tree entirely. That's why it is in state D. You can still do work with the repository, but you cannot use the regular tools in the regular way.
With your merge, what you can do is delete the bad symbolic links entirely (safely), create correct (good) ones, and add them.
If I want to commit my code with git commit -m "Initialize commit" I'll get this error:
getting fatal: bad numeric config value 'true_' for 'color.ui': invalid unit
How can I solve it?
What does color.ui error means in git?
Welcome to SO!
Problem is that Git can't do anything with _true as a value for color.ui.
This should be fixed with by editing your git config via git config --global color.ui always.
Edit: Documentation for color.ui:
This variable determines the default value for variables such as
color.diff and color.grep that control the use of color per command
family. Its scope will expand as more commands learn configuration to
set a default for the --color option. Set it to false or never if you
prefer Git commands not to use color unless enabled explicitly with
some other configuration or the --color option. Set it to always if
you want all output not intended for machine consumption to use color,
to true or auto (this is the default since Git 1.8.4) if you want such
output to use color when written to the terminal.
Here is a question keeps me puzzled for a long time as I cannot find nice and more-or-less universal solution to it.
Lets say there are two git branches available, production and dev; each uses it's own configurable parameters for some tasks (i.e. credentials, build path, test/deployment scripts switches et cetera). Same time implementation scripts & code is common for both branches.
Now, the problem arises is - how to maintain branch-specific configuration within git repository the way required. One of common solutions out there is to use 'template' configuration file within git, symlinking and ignoring the concrete for specific branch, like
$ cat .gitignore | grep conf
/concrete.conf
$ ls -l *.conf
lrwxrwxrwx 1 1000 100 12 Oct 29 10:23 concrete.conf -> generic.conf
-rw-r--r-- 1 1000 100 0 Oct 29 10:16 generic.conf
breaking and adjusting concrete.conf on development box next. Yet not a solution I'm in pursuit for.
My requirements (ok, wishes) are:
support separate configuration file per git branch, and
keep branch-specific configuration file managed by git same time
Is it even possible? Could be (actually, preferred to be file sourced by some other one, but it's none related...)
The best that has came to my mind so far is to use post-merge hooks to adjust per-branch configuration per se from some other source ignored by git, but it stinks from the very beginning.
Any suggestions on solution of problem described ?
PS: *nix-specific suggestions (i.e. using symlinks/hardlinks) suggestions is absolutely fine, I do do have any interest in M$ targets
It is possible, and does not involve symlinking.
You do not version my.config, but a template file my.config.tpl, and a value file (with values for each branches)
prod.conf
dev.conf
Then, you can use a content filter driver, using .gitattributes declaration.
(image from "Customizing Git - Git Attributes", from "Pro Git book")
The script generate my.config file by replacing placeholder values with the values of the <branch.conf> file, each time you checkout a branch.
You can know about the current branch name with:
branch=$(git rev-parse --symbolic --abbrev-ref HEAD)
The generated actual my.config remains ignored (by the .gitignore).
That means your actual working tree does not get "dirty".
The smudge script selects the correct value file and generates the correct web.config based on the template the smudge script is applied on during a git checkout.
See a complete example at "git smudge/clean filter between branches".
I'm on a fresh install of Linux Mint.
I'm getting the following error when trying to push from any repository:
error: Malformed value for push.default: simple
error: Must be one of nothing, matching, tracking or current.
fatal: bad config file line 8 in /home/leng/.gitconfig
fatal: Could not read from remote repository.
This is very odd, because I definitely have a version that supports the simple push behavior.
The output of git --version is git version 1.8.3.2.
The contents of ~/.gitconfig:
[user]
name = My Name
email = MyEmail#website.com
[color]
ui = true
[push]
default = simple
Here's where it gets creepy.
If I change the behavior to matching (or to nothing, tracking, or current, for that matter), then attempt to push, I get the same exact error message. How is that possible? Is it caching the config somehow? I've even tried rebooting. I've even tried purging GIT completely from the system (and deleting ~/.gitconfig) then reinstalling it.
If I delete the [push] section completely from the .gitconfig file (or if I delete the file entirely), then try to push, then I get this:
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:
git config --global push.default matching
To squelch this message and adopt the new behavior now, use:
git config --global push.default simple
See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)
error: Malformed value for push.default: simple
error: Must be one of nothing, matching, tracking or current.
fatal: bad config file line 8 in /home/leng/.gitconfig
fatal: Could not read from remote repository.
...so it appears to be both acknowledging that I haven't chosen a pushing behavior, but then also saying that I've chosen an unsupported behavior. What on earth is going on here?
I even get the error if I delete ~/.gitconfig completely.
Can anyone help me out with this witchcraft?
Thanks!
EDIT:
Here is a .git/config file requested:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = ssh://{my remote repo}
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
Okay, so I fixed it, but the method is absolute witchcraft.
I tried to isolate the problem by purging GIT, deleting the config file, reinstalling GIT, then creating a local bare repository, then cloning it, then attempting to push from there. Pretty much like this:
sudo apt-get purge git-core
rm -f ~/.gitconfig
sudo apt-get install git-core
cd /git
mkdir foo
cd foo
git init --bare
cd /var/www
git clone /git/foo
cd foo
touch blah.txt
git add -A
git config --global user.name "Name"
git config --global user.email "user#email.com"
git commit -m "Blah"
git push
...same exact error message, no change there. (Still some serious witchcraft.)
Then, I deleted one of my repositories that doesn't have a local origin (it connects to its origin via SSH) and cloned the repository anew after deleting it (with a fresh git clone ssh://... command).
I got an error from the clone command:
remote: Malformed value for push.default: simple
remote: Must be one of nothing, matching, tracking or current.
Ah ha! Now it says remote instead of error. So the remote doesn't support this behavior. (That doesn't explain why the error persists on local-only repositories with local origins, then, though.)
So I then SSH'ed into the remote server and updated the git-core there to the latest version, re-attempted to clone the repository from my local machine, and it worked.
Now, I can finally git push. Insanely, this also fixed it so I can git push from the entirely local /var/www/foo to the also entirely local /git/foo (the local origin bare repository). SSH'ing into this remote server and updating it somehow - WITCHCRAFT - fixed my local machine's error.
Why on earth the entirely local repos care about an entirely different machine's GIT version is... beyond me. How utterly, utterly insane.
I had the same error message on git push.
For me it turned out that the remote user's git was an older version (1.7.2.5),
and I had recently updated the remote ~/.gitconfig to include:
[push]
default = simple
The solution was to remove this setting from the remote's configuration.
Since it seems other people are having this issue, and I found a solution HERE, I thought I'd post the solution that worked for me.
IN SHORT:
The solution I found was at this page. Evidently the best solution is to upgrade to a newer version of Git (if possible). That was not an option for me, however. From a local machine, I typed the following command:
git config -–global push.default upstream
This got rid of the Malformed value for push.default: simple error I had been getting. I'm not entirely sure what upstream does, however.
MY CONTEXT (for comparison): I had an empty (bare) repository on a remote computer, and I had a few repositories on a couple "local" workstations. I pull from the remote repository, do some work, and then push my work to the remote repository. Pushing/pulling was accomplished via SSH. Most of the time, while working on a local machine, pushing/pulling would result in the error described above.
In short, before the fix, I had the following ~/.gitconfig file on the remote machine:
[user]
name = Foo Bar
email = FooBarPerson#email.com
[diff]
external = /Users/foobar/bin/git-diff-cmd.sh
[color]
diff = auto
status = auto
branch = auto
[push]
default = simple
After entering in the above command, my ~/.gitconfig file on the remote machine changed to:
[user]
name = Foo Bar
email = FooBarPerson#email.com
[diff]
external = /Users/foobar/bin/git-diff-cmd.sh
[color]
diff = auto
status = auto
branch = auto
[push]
default = upstream
Version information:
Remote machine (repository location): 1.9.4
My laptop: 1.8.5.2 (Apple Git-48)
Other computer I work on: 1.7.7.4
Here's another site that may be useful to some people:
http://www.lorrin.org/blog/2011/10/03/argumentless-git-pull-and-git-push/comment-page-1/
On Cygwin using git-svn performing remote operations such as:
git svn rebase
git svn dcommit
etc.
Causes one of many strange error messages to occur regarding bad config files
$ git svn rebase
fatal: bad config file line 1 in /home/tj/.gitconfig
fatal: bad config file line 1 in /home/tj/.gitconfig
Cannot rebase: You have unstaged changes.
Please commit or stash them.
rebase refs/remotes/git-svn: command returned error: 1
There aren't actually any unstaged changes, that error message seems to be an artifact of the config file issue:
# On branch master
nothing to commit (working directory clean)
Occasionally it complains about other lines in the same file, or about lines in .git/config
My actual git config files are very simple, and the exact same ones work fine on other machines (which are also running Cygwin). For reference:
.gitconfig:
[user]
name = tj
email = tj#example.com
.git/config:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
preloadindex = true
[svn-remote "svn"]
url = https://url.to/repository
fetch = :refs/remotes/git-svn
The octo-spacing is a tab in the file, and looking at the file in vim with set list shows no strange characters muddling around.
The strangest part of all is that sometimes it just works without issue. However, after a short period of time, it continues showing the error messages. If anyone knows that the issue may be, or how to resolve it, I would greatly appreciate it.
Thanks!
Edit:
What I've tried so far:
Copying good config files from working machines running Cygwin
Running rebaseall in Cygwin
Reinstalling git-svn package
What I might try:
Reinstalling Cygwin (would rather not)
Edit2: Success?
After fiddling around with this for a few hours, I tried removing things from the git configs one by one and seeing if it made a difference.
Removing preloadindex = true from the .git/config file seems to have resolved the issue, though it is difficult to say for sure.
The culprit was indeed core.preloadindex = true, which does not play nice in cygwin.