<commit_before>/*******************************************************************************
 * Copyright (C) 2009, <NAME> <<EMAIL>>
 * Copyright (C) 2010, <NAME> <<EMAIL>>
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.egit.core.op;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.CoreText;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.osgi.util.NLS;

/**
 * IgnoreOperation adds resources to a .gitignore file
 *
 */
public class IgnoreOperation implements IEGitOperation {

	private IResource[] resources;

	private boolean gitignoreOutsideWSChanged;

	private ISchedulingRule schedulingRule;

	/**
	 * construct an IgnoreOperation
	 *
	 * @param resources
	 */
	public IgnoreOperation(IResource[] resources) {
		this.resources = resources;
		gitignoreOutsideWSChanged = false;
		schedulingRule = calcSchedulingRule();
	}

	public void execute(IProgressMonitor monitor) throws CoreException {
		monitor.beginTask(CoreText.IgnoreOperation_taskName, resources.length);
		try {
			for (IResource resource : resources) {
				if (monitor.isCanceled())
					break;
				// TODO This is pretty inefficient; multiple ignores in
				// the same directory cause multiple writes.

				// NB This does the same thing in
				// DecoratableResourceAdapter, but neither currently
				// consult .gitignore
				addIgnore(monitor, resource);

				monitor.worked(1);
			}
			monitor.done();
		} catch (CoreException e) {
			throw e;
		} catch (Exception e) {
			throw new CoreException(Activator.error(
					CoreText.IgnoreOperation_error, e));
		}
	}

	/**
	 * @return true if a gitignore file outside the workspace was changed. In
	 *         this case the caller may need to perform manual UI refreshes
	 *         because there was no ResourceChanged event.
	 */
	public boolean isGitignoreOutsideWSChanged() {
		return gitignoreOutsideWSChanged;
	}

	public ISchedulingRule getSchedulingRule() {
		return schedulingRule;
	}

	private void addIgnore(IProgressMonitor monitor, IResource resource)
			throws UnsupportedEncodingException, CoreException {
		IContainer container = resource.getParent();
		String entry = "/" + resource.getName() + "\n"; //$NON-NLS-1$  //$NON-NLS-2$
		ByteArrayInputStream entryBytes = asStream(entry);

		if (container instanceof IWorkspaceRoot) {
			Repository repository = RepositoryMapping.getMapping(
					resource.getProject()).getRepository();
			// .gitignore is not accessible as resource
			IPath gitIgnorePath = resource.getLocation().removeLastSegments(1)
					.append(Constants.GITIGNORE_FILENAME);
			IPath repoPath = new Path(repository.getWorkTree()
					.getAbsolutePath());<commit_msg>Team->Ignore: do not write entries for already ignored files/folders<commit_after>/*******************************************************************************
 * Copyright (C) 2009, <NAME> <<EMAIL>>
 * Copyright (C) 2010, <NAME> <<EMAIL>>
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.egit.core.op;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.CoreText;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.osgi.util.NLS;

/**
 * IgnoreOperation adds resources to a .gitignore file
 *
 */
public class IgnoreOperation implements IEGitOperation {

	private IResource[] resources;

	private boolean gitignoreOutsideWSChanged;

	private ISchedulingRule schedulingRule;

	/**
	 * construct an IgnoreOperation
	 *
	 * @param resources
	 */
	public IgnoreOperation(IResource[] resources) {
		this.resources = resources;
		gitignoreOutsideWSChanged = false;
		schedulingRule = calcSchedulingRule();
	}

	public void execute(IProgressMonitor monitor) throws CoreException {
		monitor.beginTask(CoreText.IgnoreOperation_taskName, resources.length);
		try {
			for (IResource resource : resources) {
				if (monitor.isCanceled())
					break;
				// TODO This is pretty inefficient; multiple ignores in
				// the same directory cause multiple writes.

				// NB This does the same thing in
				// DecoratableResourceAdapter, but neither currently
				// consult .gitignore
				if (!isIgnored(resource))
					addIgnore(monitor, resource);
				monitor.worked(1);
			}
			monitor.done();
		} catch (CoreException e) {
			throw e;
		} catch (Exception e) {
			throw new CoreException(Activator.error(
					CoreText.IgnoreOperation_error, e));
		}
	}

	private boolean isIgnored(IResource resource) throws IOException {
		RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
		Repository repository = mapping.getRepository();
		String path = mapping.getRepoRelativePath(resource);
		TreeWalk walk = new TreeWalk(repository);
		walk.addTree(new FileTreeIterator(repository));
		walk.setFilter(PathFilter.create(path));
		while (walk.next()) {
			WorkingTreeIterator workingTreeIterator = walk.getTree(0,
					WorkingTreeIterator.class);
			if (walk.getPathString().equals(path)) {
				return workingTreeIterator.isEntryIgnored();
			}
			if (workingTreeIterator.getEntryFileMode().equals(FileMode.TREE))
				walk.enterSubtree();
		}
		return false;
	}

	/**
	 * @return true if a gitignore file outside the workspace was changed. In
	 *         this case the caller may need to perform manual UI refreshes
	 *         because there was no ResourceChanged event.
	 */
	public boolean isGitignoreOutsideWSChanged() {
		return gitignoreOutsideWSChanged;
	}

	public ISchedulingRule getSchedulingRule() {
		return schedulingRule;
	}

	private void addIgnore(IProgressMonitor monitor, IResource resource)
			throws UnsupportedEncodingException, CoreException {
		IContainer container = resource.getParent();
		String entry = "/" + resource.getName() + "\n"; //$NON-NLS-1$  //$NON-NLS-2$
		ByteArrayInputStream entryBytes = asStream(entry);

		if (container instanceof IWorkspaceRoot) {
			Repository repository = RepositoryMapping.getMapping(
					resource.getProject()).getRepository();
			// .gitignore is not accessible as resource
			IPath gitIgnorePath = resource.getLocation().removeLastSegments(1)
					.append(Constants.GITIGNORE_FILENAME);
			IPath repoPath = new Path(repository.getWorkTree()
					.getAbsolutePath());
{'fraction_non_alphanumeric': 0.13247191011235956, 'fraction_numerical': 0.003707865168539326, 'mean_word_length': 4.802477183833116, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3111026', 'n_tokens_mistral': 2719, 'n_tokens_neox': 2430, 'n_words': 606}