Расширение файла изменений GIT [дубликат]

Большинство ответов здесь дают полезные советы, когда у вас есть одна операция async, но иногда это возникает, когда вам нужно выполнить асинхронную операцию для каждой записи в массиве или другом списке подобная структура. Искушение состоит в том, чтобы сделать это:

// WRONG
var results = [];
theArray.forEach(function(entry) {
    doSomethingAsync(entry, function(result) {
        results.push(result);
    });
});
console.log(results); // E.g., using them, returning them, etc.

Пример:

// WRONG
var theArray = [1, 2, 3];
var results = [];
theArray.forEach(function(entry) {
    doSomethingAsync(entry, function(result) {
        results.push(result);
    });
});
console.log("Results:", results); // E.g., using them, returning them, etc.

function doSomethingAsync(value, callback) {
    console.log("Starting async operation for " + value);
    setTimeout(function() {
        console.log("Completing async operation for " + value);
        callback(value * 2);
    }, Math.floor(Math.random() * 200));
}
.as-console-wrapper {
  max-height: 100% !important;
}

Причина, 't работа заключается в том, что обратные вызовы из doSomethingAsync еще не запущены к тому моменту, когда вы пытаетесь использовать результаты.

Итак, если у вас есть массив (или список какого-то типа) и хотите выполнять асинхронные операции для каждой записи, у вас есть два варианта: выполнять операции параллельно (перекрывающиеся) или последовательно (последовательно последовательно).

Параллельный

Вы могут запускать все из них и отслеживать количество обратных вызовов, которые вы ожидаете, а затем использовать результаты, когда вы получили много обратных вызовов:

var results = [];
var expecting = theArray.length;
theArray.forEach(function(entry, index) {
    doSomethingAsync(entry, function(result) {
        results[index] = result;
        if (--expecting === 0) {
            // Done!
            console.log("Results:", results); // E.g., using the results
        }
    });
});

Пример:

var theArray = [1, 2, 3];
var results = [];
var expecting = theArray.length;
theArray.forEach(function(entry, index) {
    doSomethingAsync(entry, function(result) {
        results[index] = result;
        if (--expecting === 0) {
            // Done!
            console.log("Results:", results); // E.g., using the results
        }
    });
});

function doSomethingAsync(value, callback) {
    console.log("Starting async operation for " + value);
    setTimeout(function() {
        console.log("Completing async operation for " + value);
        callback(value * 2);
    }, Math.floor(Math.random() * 200));
}
.as-console-wrapper {
  max-height: 100% !important;
}

(Мы могли бы покончить с expecting и просто использовать results.length === theArray.length, но это оставляет нам открытым возможность того, что theArray изменяется, пока вызовы выдающиеся ...)

Обратите внимание, как мы используем index из forEach, чтобы сохранить результат в results в том же положении, что и запись это относится, даже если результаты a (поскольку асинхронные вызовы не обязательно завершаются в том порядке, в котором они были запущены).

Но что, если вам нужно вернуть те результаты от функции? Как указывали другие ответы, вы не можете; вы должны принять вашу функцию и вызвать обратный вызов (или вернуть Promise ). Вот вариант обратного вызова:

function doSomethingWith(theArray, callback) {
    var results = [];
    var expecting = theArray.length;
    theArray.forEach(function(entry, index) {
        doSomethingAsync(entry, function(result) {
            results[index] = result;
            if (--expecting === 0) {
                // Done!
                callback(results);
            }
        });
    });
}
doSomethingWith(theArray, function(results) {
    console.log("Results:", results);
});

Пример:

function doSomethingWith(theArray, callback) {
    var results = [];
    var expecting = theArray.length;
    theArray.forEach(function(entry, index) {
        doSomethingAsync(entry, function(result) {
            results[index] = result;
            if (--expecting === 0) {
                // Done!
                callback(results);
            }
        });
    });
}
doSomethingWith([1, 2, 3], function(results) {
    console.log("Results:", results);
});

function doSomethingAsync(value, callback) {
    console.log("Starting async operation for " + value);
    setTimeout(function() {
        console.log("Completing async operation for " + value);
        callback(value * 2);
    }, Math.floor(Math.random() * 200));
}
.as-console-wrapper {
  max-height: 100% !important;
}

Или вот версия, возвращающая Promise вместо:

function doSomethingWith(theArray) {
    return new Promise(function(resolve) {
        var results = [];
        var expecting = theArray.length;
        theArray.forEach(function(entry, index) {
            doSomethingAsync(entry, function(result) {
                results[index] = result;
                if (--expecting === 0) {
                    // Done!
                    resolve(results);
                }
            });
        });
    });
}
doSomethingWith(theArray).then(function(results) {
    console.log("Results:", results);
});

Конечно, если doSomethingAsync передал нам ошибки, мы использовали бы reject, чтобы отклонить обещание, когда мы получили сообщение об ошибке.)

Пример:

function doSomethingWith(theArray) {
    return new Promise(function(resolve) {
        var results = [];
        var expecting = theArray.length;
        theArray.forEach(function(entry, index) {
            doSomethingAsync(entry, function(result) {
                results[index] = result;
                if (--expecting === 0) {
                    // Done!
                    resolve(results);
                }
            });
        });
    });
}
doSomethingWith([1, 2, 3]).then(function(results) {
    console.log("Results:", results);
});

function doSomethingAsync(value, callback) {
    console.log("Starting async operation for " + value);
    setTimeout(function() {
        console.log("Completing async operation for " + value);
        callback(value * 2);
    }, Math.floor(Math.random() * 200));
}
.as-console-wrapper {
  max-height: 100% !important;
}

(Или, альтернативно, вы можете сделать обертку для doSomethingAsync, который возвращает обещание, а затем сделайте следующее ...)

Если doSomethingAsync дает вам Promise , вы можете использовать Promise.all :

function doSomethingWith(theArray) {
    return Promise.all(theArray.map(function(entry) {
        return doSomethingAsync(entry, function(result) {
            results.push(result);
        });
    }));
}
doSomethingWith(theArray).then(function(results) {
    console.log("Results:", results);
});

Пример:

function doSomethingWith(theArray) {
    return Promise.all(theArray.map(function(entry) {
        return doSomethingAsync(entry, function(result) {
            results.push(result);
        });
    }));
}
doSomethingWith([1, 2, 3]).then(function(results) {
    console.log("Results:", results);
});

function doSomethingAsync(value) {
    console.log("Starting async operation for " + value);
    return new Promise(function(resolve) {
        setTimeout(function() {
            console.log("Completing async operation for " + value);
            resolve(value * 2);
        }, Math.floor(Math.random() * 200));
    });
}
.as-console-wrapper {
  max-height: 100% !important;
}

Обратите внимание, что Promise.all решает свое обещание с помощью массива результатов всех обещаний, которые вы даете ему, когда все они разрешены, или отвергает его обещание, когда первый обещаний, которые вы ему даете, отклоняет.

Серия

Предположим, вы не хотите, чтобы операции были параллельны? Если вы хотите запускать их один за другим, вам нужно дождаться завершения каждой операции до начала следующего. Вот пример функции, которая делает это, и вызывает обратный вызов с результатом:

function doSomethingWith(theArray, callback) {
    var results = [];
    doOne(0);
    function doOne(index) {
        if (index < theArray.length) {
            doSomethingAsync(theArray[index], function(result) {
                results.push(result);
                doOne(index + 1);
            });
        } else {
            // Done!
            callback(results);
        }
    }
}
doSomethingWith(theArray, function(results) {
    console.log("Results:", results);
});

(Поскольку мы выполняем работу последовательно, мы можем просто использовать results.push(result), так как мы знаю, что мы не получим результаты не в порядке. В приведенном выше примере мы могли бы использовать results[index] = result;, но в некоторых из следующих примеров у нас нет индекса для использования.)

Пример:

function doSomethingWith(theArray, callback) {
    var results = [];
    doOne(0);
    function doOne(index) {
        if (index < theArray.length) {
            doSomethingAsync(theArray[index], function(result) {
                results.push(result);
                doOne(index + 1);
            });
        } else {
            // Done!
            callback(results);
        }
    }
}
doSomethingWith([1, 2, 3], function(results) {
    console.log("Results:", results);
});

function doSomethingAsync(value, callback) {
    console.log("Starting async operation for " + value);
    setTimeout(function() {
        console.log("Completing async operation for " + value);
        callback(value * 2);
    }, Math.floor(Math.random() * 200));
}
.as-console-wrapper {
  max-height: 100% !important;
}

(Или снова создайте обертку для doSomethingAsync, которая дает вам обещание и выполните ниже ...)

Если doSomethingAsync дает вам обещание, если вы можете использовать синтаксис ES2017 + (возможно, с транспилером, например Babel ), вы можете использовать функцию async с помощью for-of и await :

async function doSomethingWith(theArray) {
    const results = [];
    for (const entry of theArray) {
        results.push(await doSomethingAsync(entry));
    }
    return results;
}
doSomethingWith(theArray).then(results => {
    console.log("Results:", results);
});

Пример:

async function doSomethingWith(theArray) {
    const results = [];
    for (const entry of theArray) {
        results.push(await doSomethingAsync(entry));
    }
    return results;
}
doSomethingWith([1, 2, 3]).then(function(results) {
    console.log("Results:", results);
});

function doSomethingAsync(value) {
    console.log("Starting async operation for " + value);
    return new Promise(function(resolve) {
        setTimeout(function() {
            console.log("Completing async operation for " + value);
            resolve(value * 2);
        }, Math.floor(Math.random() * 200));
    });
}
.as-console-wrapper {
  max-height: 100% !important;
}

Если вы не можете использовать синтаксис ES2017 + (пока), вы можете использовать вариацию на Обещают уменьшить шаблон (это сложнее, чем обычное сокращение Promise, потому что мы не передаем результат от одного к другому, а вместо gat

function doSomethingWith(theArray) {
    return theArray.reduce(function(p, entry) {
        return p.then(function(results) {
            return doSomethingAsync(entry).then(function(result) {
                results.push(result);
                return results;
            });
        });
    }, Promise.resolve([]));
}
doSomethingWith(theArray).then(function(results) {
    console.log("Results:", results);
});

Пример:

function doSomethingWith(theArray) {
    return theArray.reduce(function(p, entry) {
        return p.then(function(results) {
            return doSomethingAsync(entry).then(function(result) {
                results.push(result);
                return results;
            });
        });
    }, Promise.resolve([]));
}
doSomethingWith([1, 2, 3]).then(function(results) {
    console.log("Results:", results);
});

function doSomethingAsync(value) {
    console.log("Starting async operation for " + value);
    return new Promise(function(resolve) {
        setTimeout(function() {
            console.log("Completing async operation for " + value);
            resolve(value * 2);
        }, Math.floor(Math.random() * 200));
    });
}
.as-console-wrapper {
  max-height: 100% !important;
}

.. , который менее громоздк с функциями стрелок ES2015 + :

function doSomethingWith(theArray) {
    return theArray.reduce((p, entry) => p.then(results => doSomethingAsync(entry).then(result => {
        results.push(result);
        return results;
    })), Promise.resolve([]));
}
doSomethingWith(theArray).then(results => {
    console.log("Results:", results);
});

Пример:

function doSomethingWith(theArray) {
    return theArray.reduce((p, entry) => p.then(results => doSomethingAsync(entry).then(result => {
        results.push(result);
        return results;
    })), Promise.resolve([]));
}
doSomethingWith([1, 2, 3]).then(function(results) {
    console.log("Results:", results);
});

function doSomethingAsync(value) {
    console.log("Starting async operation for " + value);
    return new Promise(function(resolve) {
        setTimeout(function() {
            console.log("Completing async operation for " + value);
            resolve(value * 2);
        }, Math.floor(Math.random() * 200));
    });
}
.as-console-wrapper {
  max-height: 100% !important;
}

844
задан Gil Shulman 25 July 2014 в 22:23
поделиться

11 ответов

Я несколько раз сталкивался с этой проблемой в MacOS. Git чувствителен к регистру, но Mac - только сохранение случаев.

Кто-то фиксирует файл: Foobar.java и через несколько дней решает переименовать его в FooBar.java. Когда вы вытаскиваете последний код, он терпит неудачу с The following untracked working tree files would be overwritten by checkout...

. Единственный надежный способ, который я видел, который исправляет это:

  1. git rm Foobar.java
  2. Зафиксируйте его сообщением, которое вы не можете пропустить. git commit -m 'TEMP COMMIT!!'
  3. Pull
  4. Это вызовет конфликт, который заставит вас объединить конфликт, потому что ваше изменение удалило его, но другое изменение переименовано (следовательно, проблема). Примите свое изменение, которое является «удалением» git rebase --continue
  5. . Теперь оставьте свое обходное git rebase -i HEAD~2 и drop TEMP COMMIT!!
  6. Убедитесь, что файл теперь называется FooBar.java
3
ответ дан Ashwin Jayaprakash 26 August 2018 в 08:16
поделиться

Использование SourceTree Я смог сделать все это из UI

  • Переименовать FILE.ext в whatever.ext
  • Сцена, что файл
  • Теперь переименуем whatever.ext в file.ext
  • Снова этот файл

Это немного утомительно, но если вам нужно всего лишь сделать это с несколькими файлами, это довольно быстро

69
ответ дан Chris Barr 26 August 2018 в 08:16
поделиться

Я попробовал следующие решения из других ответов, и они не работали:

Если ваш репозиторий размещен на GitHub, как у меня, вы можете переименовать файл по происхождению (GitHub.com) и принудительно переименовать файл в нисходящем порядке манера. Вот что я сделал:

  1. Посетите GitHub.com
  2. Перейдите в свой репозиторий на GitHub.com и выберите ветку, в которой вы работаете
  3. Перейдите к файлу, который вы намереваетесь переименовать, используя инструмент навигации по сайту.
  4. Нажмите значок «Изменить этот файл» (он выглядит как карандаш)
  5. Измените имя файла в тексте файла вход
  6. Убедитесь, что выбрана «Commit непосредственно на branchname ветви»
  7. Нажмите кнопку «Зафиксировать изменения»
  8. Локально, проверка / вытягивание / выберите ветку
  9. Готово
5
ответ дан gmeben 26 August 2018 в 08:16
поделиться

Mac OSX High Sierra 10.13 исправляет это несколько. Просто создайте виртуальный раздел APFS для своих проектов git, по умолчанию он не имеет ограничения по размеру и не занимает места.

  1. В Disk Utility нажмите кнопку +, когда выбран контейнер контейнера
  2. Выберите APFS (чувствительный к регистру) в формате
  3. Назовите его Sensitive
  4. Прибыль
  5. Дополнительно: создайте папку в разделе Чувствительность, называемая git и ln -s /Volumes/Sensitive/git /Users/johndoe/git

Ваш диск будет находиться в /Volumes/Sensitive/

Как сделать Я фиксирую только изменения имени файла в Git?

1
ответ дан Ray Foss 26 August 2018 в 08:16
поделиться

1) переименуйте файл Name.jpg в name1.jpg

2) зафиксируйте удаленный файл Name.jpg

3) переименуйте файл name1.jpg в name.jpg

4) добавляет добавленный файл name.jpg к предыдущему commit

git add
git commit --amend
14
ответ дан razon 26 August 2018 в 08:16
поделиться

Вы можете использовать git mv :

git mv -f OldFileNameCase newfilenamecase
1066
ответ дан RezaRahmati 26 August 2018 в 08:16
поделиться

Когда вы сделали много переименования файлов, а некоторые из них - просто замена корпуса, трудно вспомнить, что именно. вручную «git moving», файл может быть весьма полезной. Итак, что бы я делал во время моих задач смены имени файла:

  1. удалять все не-git-файлы и папку в другую папку / репозиторий.
  2. фиксировать текущую пустую папку git ( это будет отображаться по мере удаления всех файлов.)
  3. добавить все файлы обратно в исходную папку / репозиторий git.
  4. фиксировать текущую непустую папку git.

Это устранит все проблемы, не пытаясь определить, какие файлы или папки вы переименовали.

2
ответ дан Ricardo Virtudazo Jr 26 August 2018 в 08:16
поделиться

Это то, что я сделал в OS X:

git mv File file.tmp
git mv file.tmp file

Два шага, потому что в противном случае я получил ошибку «файл существует». Возможно, это можно сделать за один шаг, добавив --cached или такой.

84
ответ дан Sijmen Mulder 26 August 2018 в 08:16
поделиться

Иногда полезно временно изменить чувствительность регистра Git. Вот два возможных метода: -

Метод 1:

git -c core.ignorecase= <<true or false>> <<command>> можно использовать для изменения чувствительности к регистру для одна команда. Например: git -c core.ignorecase=true checkout mybranch. (кредит для VonC для предложения этого в комментариях.)

Способ 2:

Чтобы изменить настройку дольше (например, если несколько команд должны быть перед тем, как изменить его):

  1. git config core.ignorecase (это возвращает текущую настройку, например false).
  2. git config core.ignorecase <<true or false>> - установите желаемую новую настройку.
  3. ... Запустите несколько других команд ...
  4. git config core.ignorecase <<false or true>> - установить конфигурацию значение возвращается к предыдущей настройке.
4
ответ дан Steve Chambers 26 August 2018 в 08:16
поделиться

Git имеет настройку конфигурации, которая указывает, будет ли регистр чувствителен к регистру или нечувствителен: core.ignorecase. Чтобы сообщить Git, чтобы он был случайным, просто установите для этого параметра значение false:

git config core.ignorecase false

Документация

Из документации git config :

core.ignorecase

Если true, эта опция позволяет использовать различные обходные пути, чтобы git лучше работал на файловых системах, которые не чувствительны к регистру, например FAT. Например, если список каталогов обнаруживает makefile, когда git ожидает Makefile, git будет считать, что это действительно тот же файл, и продолжает помнить его как Makefile.

По умолчанию установлено значение false, кроме git-clone (1) или git-init (1) проверит и установит core.ignorecase true, если это необходимо, когда создается репозиторий.

Нечувствительные к регистру файловые системы

Две самые популярные операционные системы, в которых я не знаю файловые системы, не зависящие от регистра,

  • Windows
  • OS X
683
ответ дан user 26 August 2018 в 08:16
поделиться

В OSX, чтобы избежать этой проблемы и избежать других проблем с разработкой в ​​файловой системе без регистра, вы можете использовать Disk Utility для создания образа диска с чувствительным -чувствительным .

Запустите утилиту диска, создайте новый образ диска и используйте следующие настройки (или измените по своему усмотрению, но сохраните его с учетом регистра):

Mac Disk Utility Screenshot [/g1]

Обязательно сообщите git, что теперь он находится на чувствительном к регистру FS:

git config core.ignorecase false
36
ответ дан user1821510 26 August 2018 в 08:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: