Why is git erroring with 'Assertion failed' on git add .? - xcode

I forked a repo, then cloned it to my Mac into a /YATC directory. I had a previously-created Xcode project (TwitterTimeline) in another directory, which I copied into the /YATC directory. I did git add . in the /YATC directory, and only an empty TwitterTimeline directory was added to the repo. No other files were added. I later found out that there was already a .git directory in TwitterTimeline. I think Xcode must have created that, although I don't recall ever asking it to.
Anyway, I deleted the TwitterTimeline/.git directory. I went back up to /YATC and tried to do git add . there, and nothing happened. Meaning I immediately did git status, and it said there was nothing to commit. Then I went down to the TwitterTimeline directory and did git add ., and got the following:
Assertion failed: (item->nowildcard_len <= item->len && item->prefix <= item->len), function prefix_pathspec, file pathspec.c, line 308.
Abort trap: 6
What is this?

Not sure exactly what's happening but I was in the same situation
I moved one git repo inside another
deleted the .git dir thinking it would become a regular subdir
tried to git add -A .
got the weird error message
I got around it by renaming the subdir, doing git add from a parent dir, then renaming the subdir back to the original name. Somehow that seemed to get git back in a working state.

Basically the problem is known and it usually affects submodules. It's not Git bug, but basically instead of assert you should see the proper error that specific pathspec is part of the submodule.
The following Git patch from Stefan Beller fixes that problem:
--- a/pathspec.c
+++ b/pathspec.c
## -313,8 +313,23 ## static unsigned prefix_pathspec(struct pathspec_item *item,
}
/* sanity checks, pathspec matchers assume these are sane */
- assert(item->nowildcard_len <= item->len &&
- item->prefix <= item->len);
+ if (item->nowildcard_len > item->len ||
+ item->prefix > item->len) {
+ /* Historically this always was a submodule issue */
+ for (i = 0; i < active_nr; i++) {
+ struct cache_entry *ce = active_cache[i];
+ int ce_len = ce_namelen(ce);
+ int len = ce_len < item->len ? ce_len : item->len;
+ if (!S_ISGITLINK(ce->ce_mode))
+ continue;
+ if (!memcmp(ce->name, item->match, len))
+ die (_("Pathspec '%s' is in submodule '%.*s'"),
+ item->original, ce_len, ce->name);
+ }
+ /* The error is a new unknown bug */
+ die ("BUG: item->nowildcard_len > item->len || item->prefix > item->len)");
+ }
+
return magic;
}
One of the reason could be that the directory where you're adding the files is still registered as a submodule in the index, but actually it's not a valid git repository (e.g. it's missing .git directory).
So you should either:
initialize and update your submodules by:
git submodule init
git submodule update
Run from the parent directory where you had the error.
Make sure all non-initialized submodules have empty directories, so move any files out of there temporary.
or if you don't need this submodule, remove it:
git rm -f --cached subrepo
Run from the parent directory where you had the error.
Then try adding the files again.
See also:
[PATCH] pathspec: give better message for submodule related pathspec error
Re: [PATCH] pathspec: adjust prefixlen after striping trailing slash
assert failed in submodule edge case,
"item->nowildcard_len" in Google.

I got this problem too,Here is my way to fix this:
delete the .git folder in the submodule folder(if you did this before, go 2)
then excute follow command, directory is your submodule folder
git rm --cached directory
git add directory
then you can upload this folder like others

The only way i was able to get around this error, after
Deleting the .git folder
git deinit
git rm
going over these links git fatal pathspec submodule , deleting local repo , assert failed in submodule
was to rename directory and then add it again.

Related

git apply error no such file or directory

I have two sepearate git repos: A and B. Some repository B files are already present in a subfolder of project A. My goal is to create patches for repo B and then applying them to the subfolder within repo A to conserve history of repo B while merging them. The issue is that a patch is unable to create new files. For example:
assuming this folder structure: /home/user/B/..bunch of directories and /home/user/A/ext/lib/B/..bunch of directories
cd /home/user/B
git format-patch "xx..xx" -o /home/user/A/ (create patch files)
cd /home/user/A
git apply -v --directory=ext/lib/B/ 0001-foo-12345.patch
works fine since the patch is not creating any new files or trying to access a folder which is present in B but not A
BUT
cd /home/user/A
git apply -v --directory=ext/lib/B/ 0002-foo2-6789.patch
does not work and throws this error:
Checking patch ext/lib/B/xyz/test.c...
error: ext/lib/B/xyz/test.c: No such file or directory.
I have tried the following commands so far:
git apply -v --directory=/home/user/A/lib/B/ --include=bb/cc --exclude=cc/ --exclude=bb/ --include=* 0002-foo2-6789.patch
git apply -v --directory=/home/user/A/lib/B/ --include=* --include=bb/cc --exclude=cc/ --exclude=bb/ 0002-foo2-6789.patch
git am --directory=/home/user/A/lib/B/ --include=* --include=bb/cc --exclude=cc/ --exclude=bb/ 0002-foo2-6789.patch
1.create patch file:
git diff --cached >> test.patch
2.use the patch:
git apply -p1 < test.patch
There are a number of ways to create patch files that will create new files. However, creating patches in repo B and applying them in repo A won't import the history of repo B into repo A. Is that what you mean by "conserve history of repo B while merging them"?
Example patch that causes git apply to create a new path:
diff --git a/b1.txt b/b1.txt
new file mode 100644 <-- lines specific to creating new files
index 0000000..12f00e9
--- /dev/null <-- lines specific to creating new files
+++ b/b1.txt
## -0,0 +1 ##
+contents
One way to create patches like this is to copy the files from repo B to their destination in repo A, git add any changed or new files, then use git diff --staged > my.patch to create a patch for all changed and new files. However, by then, the files are already in repo A, so there's little point in creating a such patch, and this also won't import repo B's history into repo A.
If you really want to merge repo B into a subdirectory of repo A and preserver the history of both, you're better off not using patches and looking at the top several answers here: How do you merge two Git repositories?

How to remove directory named 'Module - Copy20102018' with spaces from GIT repository

Wanted to remove the following directory from git repository.
Module - Copy20102018
I have removed one directory named 'Module - Copy20102018' directly.
This folder was there in the git repository.
Now in git status this directory shows under header 'changes are not staged for commit'.
deleted: app/code/Module - Copy20102018/system.xml
deleted: app/code/Module - Copy20102018/etc.xml
deleted: app/code/Module - Copy20102018/123.php
deleted: app/code/Module - Copy20102018/Report/JS/script.js
deleted: app/code/Module - Copy20102018/Report/CSS/style.css
When I tried to run any of the following commands.
git add app/code/Module - Copy20102018
Gives message: fatal: pathspec '-' did not match any files
git rm app/code/Module - Copy20102018
Gives message: fatal: not removing 'Module' recursively without -r
git checkout app/code/Module - Copy20102018
Gives message :
error: pathspec '-' did not match any file(s) known to git.
error: pathspec 'Copy20102018' did not match any file(s) known to git.
Any other way to remove this kind of folder from git repository.
I thought this would be a duplicate, but I cannot seem to find one - bash interprets by defaults spaces as word breaks so
git rm /a/b - c
is interpreted the same as if you ran
git rm /a/b
git rm -
git rm c
You need to quote filenames that contain spaces:
git rm '/a/b - c'
or escape the spaces. If this is a folder you need the recursive flag -r.

Git is tracking directories and will not ignore them

I must have read at least 50 StackOverflow questions and answers that say that Git cannot track directories. And yet, that is exactly what seems to be happening.
I created a project (.NET, on Windows), and added and committed all the files prior to adding a .gitignore. Realizing my mistake later on, I git rm -r --cached :/ everything, added this .gitignore, and the re-added and committed my files. The thing is, git still tracks my obj and bin folders even though they seem to be ignored in the .gitignore.
Here are the relevant lines from the .gitignore:
[Bb]in/
[Oo]bj/
bin/**
obj/**
One or two of those might not make sense, I'm not totally familiar with .gitignore rules and was just trying to see what would stick.
Here's what I get for git status:
Untracked files:
(use "git add <file>..." to include in what will be committed)
src/main/dotnet/ETB/ETB.Droid/bin/
src/main/dotnet/ETB/ETB.Droid/obj/
src/main/dotnet/ETB/ETB.iOS/bin/
src/main/dotnet/ETB/ETB.iOS/obj/
src/main/dotnet/ETB/ETB/bin/
src/main/dotnet/ETB/ETB/obj/
src/main/dotnet/packages/
This is even after I do something like git rm -r --cached .\src\main\dotnet\ETB\ETB.Droid\bin from the root level. There are also ZERO tracked files from within these directories that appear in the "Changes not staged for commit" section when I do a git status.
I'm really, really stumped. Can anyone help me figure out why I can't ignore these directories completely?
Update
I made the changes that the commenters suggested, and it seemed to solve some, but not all, of my problems (sorry I had it marked answered for a bit there). Relevant lines in my .gitignore at the root level are:
**/[Dd]ebug/**
**/bin/**
**/obj/**
That first line is probably not necessary, but I figured it couldn't hurt. There is definitely no extra whitespace on any of these lines.
For some reason, only one of the obj directories is still showing up in Git. I even deleted and re-added everything just to try it out.
The offending directory is the ETB.Data directory:
Untracked files:
(use "git add <file>..." to include in what will be committed)
src/main/dotnet/ETB.Data/
So I ran this command:
git rm -r --cached .\src\main\dotnet\
I then committed those deletes. Then I tried to re-add the directory
git add .\src\main\dotnet
When I look at my status, here is what I'm seeing:
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: src/main/dotnet/ETB.Data/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs
new file: src/main/dotnet/ETB.Data/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
new file: src/main/dotnet/ETB.Data/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs
new file: src/main/dotnet/ETB.sln
...
...
Why do these files keep showing up?! The obj and bin directories in other project directories are being ignored. Does anyone know why this one isn't being ignored?
You need to tell git to ignore all the bin/obj files/folders, not just the ones at its root :
**/bin/**
**/obj/**
From man gitignore :
A leading "**" followed by a slash means match in all directories. For example, "**/foo" matches file or directory "foo"
anywhere, the same as pattern "foo". "**/foo/bar" matches file or directory "bar" anywhere that is directly under
directory "foo".
A trailing "/**" matches everything inside. For example, "abc/**" matches all files inside directory "abc", relative to
the location of the .gitignore file, with infinite depth.
Thats very simple because your line in your .gitignore file are not correct. I can't test it now but try something like this for example
**/bin/**
**/obj/**
When you don't write the * at the beginning your line is interpreted as the start.
There is a good comment if you read the man page.
. A leading "" followed by a slash means match in all directories.
For example, "/foo" matches file or directory "foo" anywhere, the
same as pattern "foo". "**/foo/bar" matches file or directory "bar"
anywhere that is directly under directory "foo".
. A trailing "/" matches everything inside. For example, "abc/"
matches all files inside directory "abc", relative to the location of
the .gitignore file, with infinite depth.

Why is git looking inside vendors directory?

I have the .gitignore file with this code:
/app/cache/*
/app/logs/*
/app/bootstrap*
/vendor/*
/web/bundles/
/app/config/parameters.yml
but when I do :
$ git status
in any situation (before and after add and commit), I get a long text output like this:
...
# deleted: vendor/doctrine/orm/tools/sandbox/cli-config.php
# deleted: vendor/doctrine/orm/tools/sandbox/doctrine
# deleted: vendor/doctrine/orm/tools/sandbox/doctrine.php
# deleted: vendor/doctrine/orm/tools/sandbox/index.php
# deleted: vendor/doctrine/orm/tools/sandbox/xml/Entities.Address.dcm.xml
# deleted: vendor/doctrine/orm/tools/sandbox/xml/Entities.User.dcm.xml
# deleted: vendor/doctrine/orm/tools/sandbox/yaml/Entities.Address.dcm.yml
# deleted: vendor/doctrine/orm/tools/sandbox/yaml/Entities.User.dcm.yml
# modified: vendor/friendsofsymfony/user-bundle/FOS/UserBundle
# modified: vendor/gedmo/doctrine-extensions
# modified: vendor/herzult/forum-bundle/Herzult/Bundle/ForumBundle
# modified: vendor/kriswallsmith/assetic
# modified: vendor/symfony/property-access/Symfony/Component/PropertyAccess/.gitignore
# modified: vendor/symfony/property-access/Symfony/Component/PropertyAccess/StringUtil.php
# modified: vendor/symfony/symfony/CHANGELOG-2.1.md
...
The vendors directory is in .gitignore file, so I don't know what is happening.
I've tried with:
$ sudo git clean -dxf
but nothing changes.
Your vendor directory is checked in to the repo. To remove it, go to your git repo root and run:
git rm -r --cached vendor
This will recursively (due to -r flag) remove vendor from your git repo. The --cached flag will keep the local copy of vendor directory in tact. Note that if there are other devs working with the repo, their copy of the vendor directory will be removed and they will need to bundle install again.
Once you've untracked the directory in git, you can commit the change using:
git commit -m "untrack vendor directory"
Thereafter, .gitignore will happily ignore any changes within the vendor directory next time onwards.
Also, you don't need your entries in .gitignore to begin with a /. Use the / when you want to ensure that only files/folders in root directory are ignored, and any file in a subdirectory matching the pattern should not be ignored.
It looks like you already have files under vendor/* checked in. .gitignore ignores only untracked files. See also the first paragraph in man gitignore.

Git: How to ignore files on Windows?

I create .gitignore in folder with my repository near .git
project
--.git
--.gitignore
--Source
----tmp
----scr
But git doesnt see it, wouldnt ignore files in .gitignore
My .gitignore file:
*.tmp
*~
*.pdb
*.user
*.suo
Sources/tmp
What`s wrong?
Up:
I created new repositiry, add .gitignore before init commit - it work!
But if I add in old repository it doesn`t...
The problem is that you're specifying glob syntax when the default syntax for git is regex.
Try this instead:
.*\.tmp
.*~
.*\.pdb
.*\.user
.*\.suo
Sources\/tmp
What you have should work, though your directory listing has Source/ while your .gitignore has Sources/.
The one thing that springs to mind is that the line endings might not be what git is expecting.
Also, as tmp is a directory, usually a trailing '/' is used:
Source/tmp/
Finally, you can also create a .gitignore in Source/ with the line:
tmp/
instead of having it in the top directory.

Resources